ETH Price: $2,712.88 (+2.15%)
Gas: 7.64 Gwei

Token

eToro Pound sterling (GBPX)
 

Overview

Max Total Supply

500,000 GBPX

Holders

478 (0.00%)

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

GBPX is one of the stable coins that are offered for trading on eToroX.

# Exchange Pair Price  24H Volume % Volume

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x8E4d222d...5C3dA78E0
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
EToken

Compiler Version
v0.4.24+commit.e67f0147

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

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

pragma solidity ^0.4.24;

// File: contracts/token/IETokenProxy.sol

/**
 * MIT License
 *
 * Copyright (c) 2019 eToroX Labs
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

pragma solidity 0.4.24;

/**
 * @title Interface of an upgradable token
 * @dev See implementation for
 */
interface IETokenProxy {

    /* solium-disable zeppelin/missing-natspec-comments */

    /* Taken from ERC20Detailed in openzeppelin-solidity */
    function nameProxy(address sender) external view returns(string);

    function symbolProxy(address sender)
        external
        view
        returns(string);

    function decimalsProxy(address sender)
        external
        view
        returns(uint8);

    /* Taken from IERC20 in openzeppelin-solidity */
    function totalSupplyProxy(address sender)
        external
        view
        returns (uint256);

    function balanceOfProxy(address sender, address who)
        external
        view
        returns (uint256);

    function allowanceProxy(address sender,
                            address owner,
                            address spender)
        external
        view
        returns (uint256);

    function transferProxy(address sender, address to, uint256 value)
        external
        returns (bool);

    function approveProxy(address sender,
                          address spender,
                          uint256 value)
        external
        returns (bool);

    function transferFromProxy(address sender,
                               address from,
                               address to,
                               uint256 value)
        external
        returns (bool);

    function mintProxy(address sender, address to, uint256 value)
        external
        returns (bool);

    function changeMintingRecipientProxy(address sender,
                                         address mintingRecip)
        external;

    function burnProxy(address sender, uint256 value) external;

    function burnFromProxy(address sender,
                           address from,
                           uint256 value)
        external;

    function increaseAllowanceProxy(address sender,
                                    address spender,
                                    uint addedValue)
        external
        returns (bool success);

    function decreaseAllowanceProxy(address sender,
                                    address spender,
                                    uint subtractedValue)
        external
        returns (bool success);

    function pauseProxy(address sender) external;

    function unpauseProxy(address sender) external;

    function pausedProxy(address sender) external view returns (bool);

    function finalizeUpgrade() external;
}

// File: contracts/token/IEToken.sol

/**
 * MIT License
 *
 * Copyright (c) 2019 eToroX Labs
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

pragma solidity 0.4.24;


/**
 * @title EToken interface
 * @dev The interface comprising an EToken contract
 * This interface is a superset of the ERC20 interface defined at
 * https://github.com/ethereum/EIPs/issues/20
 */
interface IEToken {

    /* solium-disable zeppelin/missing-natspec-comments */

    function upgrade(IETokenProxy upgradedToken) external;

    /* Taken from ERC20Detailed in openzeppelin-solidity */
    function name() external view returns(string);

    function symbol() external view returns(string);

    function decimals() external view returns(uint8);

    /* Taken from IERC20 in openzeppelin-solidity */
    function totalSupply() external view returns (uint256);

    function balanceOf(address who) external view returns (uint256);

    function allowance(address owner, address spender)
        external view returns (uint256);

    function transfer(address to, uint256 value) external returns (bool);

    function approve(address spender, uint256 value)
        external
        returns (bool);

    function transferFrom(address from, address to, uint256 value)
        external
        returns (bool);

    /* Taken from ERC20Mintable */
    function mint(address to, uint256 value) external returns (bool);

    /* Taken from ERC20Burnable */
    function burn(uint256 value) external;

    function burnFrom(address from, uint256 value) external;

    /* Taken from ERC20Pausable */
    function increaseAllowance(
        address spender,
        uint addedValue
    )
        external
        returns (bool success);

    function pause() external;

    function unpause() external;

    function paused() external view returns (bool);

    function decreaseAllowance(
        address spender,
        uint subtractedValue
    )
        external
        returns (bool success);

    event Transfer(
        address indexed from,
        address indexed to,
        uint256 value
    );

    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );

}

// File: openzeppelin-solidity/contracts/ownership/Ownable.sol

/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
  address private _owner;

  event OwnershipTransferred(
    address indexed previousOwner,
    address indexed newOwner
  );

  /**
   * @dev The Ownable constructor sets the original `owner` of the contract to the sender
   * account.
   */
  constructor() internal {
    _owner = msg.sender;
    emit OwnershipTransferred(address(0), _owner);
  }

  /**
   * @return the address of the owner.
   */
  function owner() public view returns(address) {
    return _owner;
  }

  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
    require(isOwner());
    _;
  }

  /**
   * @return true if `msg.sender` is the owner of the contract.
   */
  function isOwner() public view returns(bool) {
    return msg.sender == _owner;
  }

  /**
   * @dev Allows the current owner to relinquish control of the contract.
   * @notice Renouncing to ownership will leave the contract without an owner.
   * It will not be possible to call the functions with the `onlyOwner`
   * modifier anymore.
   */
  function renounceOwnership() public onlyOwner {
    emit OwnershipTransferred(_owner, address(0));
    _owner = address(0);
  }

  /**
   * @dev Allows the current owner to transfer control of the contract to a newOwner.
   * @param newOwner The address to transfer ownership to.
   */
  function transferOwnership(address newOwner) public onlyOwner {
    _transferOwnership(newOwner);
  }

  /**
   * @dev Transfers control of the contract to a newOwner.
   * @param newOwner The address to transfer ownership to.
   */
  function _transferOwnership(address newOwner) internal {
    require(newOwner != address(0));
    emit OwnershipTransferred(_owner, newOwner);
    _owner = newOwner;
  }
}

// File: openzeppelin-solidity/contracts/math/SafeMath.sol

/**
 * @title SafeMath
 * @dev Math operations with safety checks that revert on error
 */
library SafeMath {

  /**
  * @dev Multiplies two numbers, reverts on overflow.
  */
  function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
    // benefit is lost if 'b' is also tested.
    // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
    if (a == 0) {
      return 0;
    }

    uint256 c = a * b;
    require(c / a == b);

    return c;
  }

  /**
  * @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
  */
  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b > 0); // Solidity only automatically asserts when dividing by 0
    uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold

    return c;
  }

  /**
  * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
  */
  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b <= a);
    uint256 c = a - b;

    return c;
  }

  /**
  * @dev Adds two numbers, reverts on overflow.
  */
  function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    require(c >= a);

    return c;
  }

  /**
  * @dev Divides two numbers and returns the remainder (unsigned integer modulo),
  * reverts when dividing by zero.
  */
  function mod(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b != 0);
    return a % b;
  }
}

// File: contracts/token/ERC20/Storage.sol

/**
 * MIT License
 *
 * Copyright (c) 2019 eToroX Labs
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

pragma solidity 0.4.24;



/**
 * @title External ERC20 Storage
 *
 * @dev The storage contract used in ExternalERC20 token. This contract can
 * provide storage for exactly one contract, referred to as the implementor,
 * inheriting from the ExternalERC20 contract. Only the current implementor or
 * the owner can transfer the implementorship. Change of state is only allowed
 * by the implementor.
 */
contract Storage is Ownable {
    using SafeMath for uint256;

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

    address private _implementor;

    event StorageImplementorTransferred(address indexed from,
                                        address indexed to);

    /**
     * @dev Contructor.
     * @param owner The address of the owner of the contract.
     * Must not be the zero address.
     * @param implementor The address of the contract that is
     * allowed to change state. Must not be the zero address.
     */
    constructor(address owner, address implementor) public {

        require(
            owner != address(0),
            "Owner should not be the zero address"
        );

        require(
            implementor != address(0),
            "Implementor should not be the zero address"
        );

        transferOwnership(owner);
        _implementor = implementor;
    }

    /**
     * @dev Return whether the sender is an implementor.
     */
    function isImplementor() public view returns(bool) {
        return msg.sender == _implementor;
    }

    /**
     * @dev Sets new balance.
     * Can only be done by owner or implementor contract.
     */
    function setBalance(address owner,
                        uint256 value)
        public
        onlyImplementor
    {
        balances[owner] = value;
    }

    /**
     * @dev Increases the balances relatively
     * @param owner the address for which to increase balance
     * @param addedValue the value to increase with
     */
    function increaseBalance(address owner, uint256 addedValue)
        public
        onlyImplementor
    {
        balances[owner] = balances[owner].add(addedValue);
    }

    /**
     * @dev Decreases the balances relatively
     * @param owner the address for which to decrease balance
     * @param subtractedValue the value to decrease with
     */
    function decreaseBalance(address owner, uint256 subtractedValue)
        public
        onlyImplementor
    {
        balances[owner] = balances[owner].sub(subtractedValue);
    }

    /**
     * @dev Can only be done by owner or implementor contract.
     * @return The current balance of owner
     */
    function getBalance(address owner)
        public
        view
        returns (uint256)
    {
        return balances[owner];
    }

    /**
     * @dev Sets new allowance.
     * Can only be called by implementor contract.
     */
    function setAllowed(address owner,
                        address spender,
                        uint256 value)
        public
        onlyImplementor
    {
        allowed[owner][spender] = value;
    }

    /**
     * @dev Increases the allowance relatively
     * @param owner the address for which to allow from
     * @param spender the addres for which the allowance increase is granted
     * @param addedValue the value to increase with
     */
    function increaseAllowed(
        address owner,
        address spender,
        uint256 addedValue
    )
        public
        onlyImplementor
    {
        allowed[owner][spender] = allowed[owner][spender].add(addedValue);
    }

    /**
     * @dev Decreases the allowance relatively
     * @param owner the address for which to allow from
     * @param spender the addres for which the allowance decrease is granted
     * @param subtractedValue the value to decrease with
     */
    function decreaseAllowed(
        address owner,
        address spender,
        uint256 subtractedValue
    )
        public
        onlyImplementor
    {
        allowed[owner][spender] = allowed[owner][spender].sub(subtractedValue);
    }

    /**
     * @dev Can only be called by implementor contract.
     * @return The current allowance for spender from owner
     */
    function getAllowed(address owner,
                        address spender)
        public
        view
        returns (uint256)
    {
        return allowed[owner][spender];
    }

    /**
     * @dev Change totalSupply.
     * Can only be called by implementor contract.
     */
    function setTotalSupply(uint256 value)
        public
        onlyImplementor
    {
        totalSupply = value;
    }

    /**
     * @dev Can only be called by implementor contract.
     * @return Current supply
     */
    function getTotalSupply()
        public
        view
        returns (uint256)
    {
        return totalSupply;
    }

    /**
     * @dev Transfer implementor to new contract
     * Can only be called by owner or implementor contract.
     */
    function transferImplementor(address newImplementor)
        public
        requireNonZero(newImplementor)
        onlyImplementorOrOwner
    {
        require(newImplementor != _implementor,
                "Cannot transfer to same implementor as existing");
        address curImplementor = _implementor;
        _implementor = newImplementor;
        emit StorageImplementorTransferred(curImplementor, newImplementor);
    }

    /**
     * @dev Asserts that sender is either owner or implementor.
     */
    modifier onlyImplementorOrOwner() {
        require(isImplementor() || isOwner(), "Is not implementor or owner");
        _;
    }

    /**
     * @dev Asserts that sender is the implementor.
     */
    modifier onlyImplementor() {
        require(isImplementor(), "Is not implementor");
        _;
    }

    /**
     * @dev Asserts that the given address is not the null-address
     */
    modifier requireNonZero(address addr) {
        require(addr != address(0), "Expected a non-zero address");
        _;
    }
}

// File: contracts/token/ERC20/ERC20.sol

/**
 * MIT License
 *
 * Copyright (c) 2019 eToroX Labs
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

pragma solidity 0.4.24;



/**
 * @title Internal implementation of ERC20 functionality with support
 * for a separate storage contract
 */
contract ERC20 {
    using SafeMath for uint256;

    Storage private externalStorage;

    string private name_;
    string private symbol_;
    uint8 private decimals_;

    event Transfer(
        address indexed from,
        address indexed to,
        uint256 value
    );

    event Approval(
        address indexed owner,
        address indexed spender,
        uint256 value
    );

    /**
     * @dev Constructor
     * @param name The ERC20 detailed token name
     * @param symbol The ERC20 detailed symbol name
     * @param decimals Determines the number of decimals of this token
     * @param _externalStorage The external storage contract.
     * Should be zero address if shouldCreateStorage is true.
     * @param initialDeployment Defines whether it should
     * create a new external storage. Should be false if
     * externalERC20Storage is defined.
     */
    constructor(
        string name,
        string symbol,
        uint8 decimals,
        Storage _externalStorage,
        bool initialDeployment
    )
        public
    {

        require(
            (_externalStorage != address(0) && (!initialDeployment)) ||
            (_externalStorage == address(0) && initialDeployment),
            "Cannot both create external storage and use the provided one.");

        name_ = name;
        symbol_ = symbol;
        decimals_ = decimals;

        if (initialDeployment) {
            externalStorage = new Storage(msg.sender, this);
        } else {
            externalStorage = _externalStorage;
        }
    }

    /**
     * @return The storage used by this contract
     */
    function getExternalStorage() public view returns(Storage) {
        return externalStorage;
    }

    /**
     * @return the name of the token.
     */
    function _name() internal view returns(string) {
        return name_;
    }

    /**
     * @return the symbol of the token.
     */
    function _symbol() internal view returns(string) {
        return symbol_;
    }

    /**
     * @return the number of decimals of the token.
     */
    function _decimals() internal view returns(uint8) {
        return decimals_;
    }

    /**
     * @dev Total number of tokens in existence
     */
    function _totalSupply() internal view returns (uint256) {
        return externalStorage.getTotalSupply();
    }

    /**
     * @dev Gets the balance of the specified address.
     * @param owner The address to query the balance of.
     * @return An uint256 representing the amount owned by the passed address.
     */
    function _balanceOf(address owner) internal view returns (uint256) {
        return externalStorage.getBalance(owner);
    }

    /**
     * @dev Function to check the amount of tokens that an owner allowed to a spender.
     * @param owner address The address which owns the funds.
     * @param spender address The address which will spend the funds.
     * @return A uint256 specifying the amount of tokens still available for the spender.
     */
    function _allowance(address owner, address spender)
        internal
        view
        returns (uint256)
    {
        return externalStorage.getAllowed(owner, spender);
    }

    /**
     * @dev Transfer token for a specified addresses
     * @param originSender The address to transfer from.
     * @param to The address to transfer to.
     * @param value The amount to be transferred.
     */
    function _transfer(address originSender, address to, uint256 value)
        internal
        returns (bool)
    {
        require(to != address(0));

        externalStorage.decreaseBalance(originSender, value);
        externalStorage.increaseBalance(to, value);

        emit Transfer(originSender, to, value);

        return true;
    }

    /**
     * @dev Approve the passed address to spend the specified amount
     * 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 originSender the original transaction sender
     * @param spender The address which will spend the funds.
     * @param value The amount of tokens to be spent.
     */
    function _approve(address originSender, address spender, uint256 value)
        internal
        returns (bool)
    {
        require(spender != address(0));

        externalStorage.setAllowed(originSender, spender, value);
        emit Approval(originSender, spender, value);

        return true;
    }

    /**
     * @dev Transfer tokens from one address to another
     * @param originSender the original transaction sender
     * @param from address The address which you want to send tokens from
     * @param to address The address which you want to transfer to
     * @param value uint256 the amount of tokens to be transferred
     */
    function _transferFrom(
        address originSender,
        address from,
        address to,
        uint256 value
    )
        internal
        returns (bool)
    {

        externalStorage.decreaseAllowed(from, originSender, value);

        _transfer(from, to, value);

        emit Approval(
            from,
            originSender,
            externalStorage.getAllowed(from, originSender)
        );

        return true;
    }

    /**
     * @dev Increase the amount of tokens that an owner allowed to a spender.
     * approve should be called when allowed_[_spender] == 0. To increment
     * allowed value is better to use this function to avoid 2 calls (and wait until
     * the first transaction is mined)
     * From MonolithDAO Token.sol
     * @param originSender the original transaction sender
     * @param spender The address which will spend the funds.
     * @param addedValue The amount of tokens to increase the allowance by.
     */
    function _increaseAllowance(
        address originSender,
        address spender,
        uint256 addedValue
    )
        internal
        returns (bool)
    {
        require(spender != address(0));

        externalStorage.increaseAllowed(originSender, spender, addedValue);

        emit Approval(
            originSender, spender,
            externalStorage.getAllowed(originSender, spender)
        );

        return true;
    }

    /**
     * @dev Decrease the amount of tokens that an owner allowed to a
     * spender.  approve should be called when allowed_[_spender] ==
     * 0. To decrement allowed value is better to use this function to
     * avoid 2 calls (and wait until the first transaction is mined)
     * From MonolithDAO Token.sol
     * @param originSender the original transaction sender
     * @param spender The address which will spend the funds.
     * @param subtractedValue The amount of tokens to decrease the allowance by.
     */
    function _decreaseAllowance(
        address originSender,
        address spender,
        uint256 subtractedValue
    )
        internal
        returns (bool)
    {
        require(spender != address(0));

        externalStorage.decreaseAllowed(originSender,
                                        spender,
                                        subtractedValue);

        emit Approval(
            originSender, spender,
            externalStorage.getAllowed(originSender, spender)
        );

        return true;
    }

    /**
     * @dev Internal function that mints an amount of the token and assigns it to
     * an account. This encapsulates the modification of balances such that the
     * proper events are emitted.
     * @param account The account that will receive the created tokens.
     * @param value The amount that will be created.
     */
    function _mint(address account, uint256 value) internal returns (bool)
    {
        require(account != 0);

        externalStorage.setTotalSupply(
            externalStorage.getTotalSupply().add(value));
        externalStorage.increaseBalance(account, value);

        emit Transfer(address(0), account, value);

        return true;
    }

    /**
     * @dev Internal function that burns an amount of the token of a given
     * account.
     * @param originSender The account whose tokens will be burnt.
     * @param value The amount that will be burnt.
     */
    function _burn(address originSender, uint256 value) internal returns (bool)
    {
        require(originSender != 0);

        externalStorage.setTotalSupply(
            externalStorage.getTotalSupply().sub(value));
        externalStorage.decreaseBalance(originSender, value);

        emit Transfer(originSender, address(0), value);

        return true;
    }

    /**
     * @dev Internal function that burns an amount of the token of a given
     * account, deducting from the sender's allowance for said account. Uses the
     * internal burn function.
     * @param originSender the original transaction sender
     * @param account The account whose tokens will be burnt.
     * @param value The amount that will be burnt.
     */
    function _burnFrom(address originSender, address account, uint256 value)
        internal
        returns (bool)
    {
        require(value <= externalStorage.getAllowed(account, originSender));

        externalStorage.decreaseAllowed(account, originSender, value);
        _burn(account, value);

        emit Approval(account, originSender,
                      externalStorage.getAllowed(account, originSender));

        return true;
    }
}

// File: contracts/token/UpgradeSupport.sol

/**
 * MIT License
 *
 * Copyright (c) 2019 eToroX Labs
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

pragma solidity 0.4.24;




/**
 * @title Functionality supporting contract upgradability
 */
contract UpgradeSupport is Ownable, ERC20 {

    event Upgraded(address indexed to);
    event UpgradeFinalized(address indexed upgradedFrom);

    /**
     * @dev Holds the address of the contract that was upgraded from
     */
    address private _upgradedFrom;
    bool private enabled;
    IETokenProxy private upgradedToken;

    /**
     * @dev Constructor
     * @param initialDeployment Set to true if this is the initial deployment of
     * the token. If true it automtically creates a new ExternalERC20Storage.
     * Also, it acts as a confirmation of intention which interlocks
     * upgradedFrom as follows: If initialDeployment is true, then
     * upgradedFrom must be the zero address. Otherwise, upgradedFrom must not
     * be the zero address. The same applies to externalERC20Storage, which must
     * be set to the zero address if initialDeployment is true.
     * @param upgradedFrom The token contract that this contract upgrades. Set
     * to address(0) for initial deployments
     */
    constructor(bool initialDeployment, address upgradedFrom) internal {
        require((upgradedFrom != address(0) && (!initialDeployment)) ||
                (upgradedFrom == address(0) && initialDeployment),
                "Cannot both be upgraded and initial deployment.");

        if (! initialDeployment) {
            // Pause until explicitly unpaused by upgraded contract
            enabled = false;
            _upgradedFrom = upgradedFrom;
        } else {
            enabled = true;
        }
    }

    modifier upgradeExists() {
        require(_upgradedFrom != address(0),
                "Must have a contract to upgrade from");
        _;
    }

    /**
     * @dev Called by the upgraded contract in order to mark the finalization of
     * the upgrade and activate the new contract
     */
    function finalizeUpgrade()
        external
        upgradeExists
        onlyProxy
    {
        enabled = true;
        emit UpgradeFinalized(msg.sender);
    }

    /**
     * Upgrades the current token
     * @param _upgradedToken The address of the token that this token
     * should be upgraded to
     */
    function upgrade(IETokenProxy _upgradedToken) public onlyOwner {
        require(!isUpgraded(), "Token is already upgraded");
        require(_upgradedToken != IETokenProxy(0),
                "Cannot upgrade to null address");
        require(_upgradedToken != IETokenProxy(this),
                "Cannot upgrade to myself");
        require(getExternalStorage().isImplementor(),
                "I don't own my storage. This will end badly.");

        upgradedToken = _upgradedToken;
        getExternalStorage().transferImplementor(_upgradedToken);
        _upgradedToken.finalizeUpgrade();
        emit Upgraded(_upgradedToken);
    }

    /**
     * @return Is this token upgraded
     */
    function isUpgraded() public view returns (bool) {
        return upgradedToken != IETokenProxy(0);
    }

    /**
     * @return The token that this was upgraded to
     */
    function getUpgradedToken() public view returns (IETokenProxy) {
        return upgradedToken;
    }

    /**
     * @dev Only allow the old contract to access the functions with explicit
     * sender passing
     */
    modifier onlyProxy () {
        require(msg.sender == _upgradedFrom,
                "Proxy is the only allowed caller");
        _;
    }

    /**
     * @dev Allows execution if token is enabled, i.e. it is the
     * initial deployment or is upgraded from a contract which has
     * called the finalizeUpgrade function.
     */
    modifier isEnabled () {
        require(enabled, "Token disabled");
        _;
    }
}

// File: openzeppelin-solidity/contracts/access/Roles.sol

/**
 * @title Roles
 * @dev Library for managing addresses assigned to a Role.
 */
library Roles {
  struct Role {
    mapping (address => bool) bearer;
  }

  /**
   * @dev give an account access to this role
   */
  function add(Role storage role, address account) internal {
    require(account != address(0));
    require(!has(role, account));

    role.bearer[account] = true;
  }

  /**
   * @dev remove an account's access to this role
   */
  function remove(Role storage role, address account) internal {
    require(account != address(0));
    require(has(role, account));

    role.bearer[account] = false;
  }

  /**
   * @dev check if an account has this role
   * @return bool
   */
  function has(Role storage role, address account)
    internal
    view
    returns (bool)
  {
    require(account != address(0));
    return role.bearer[account];
  }
}

// File: contracts/token/access/roles/PauserRole.sol

/**
 * MIT License
 *
 * Copyright (c) 2019 eToroX Labs
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

pragma solidity 0.4.24;



/** @title Contract managing the pauser role */
contract PauserRole is Ownable {
    using Roles for Roles.Role;

    event PauserAdded(address indexed account);
    event PauserRemoved(address indexed account);

    Roles.Role private pausers;

    constructor() internal {
        _addPauser(msg.sender);
    }

    modifier onlyPauser() {
        require(isPauser(msg.sender), "not pauser");
        _;
    }

    modifier requirePauser(address account) {
        require(isPauser(account), "not pauser");
        _;
    }

    /**
     * @dev Checks if account is pauser
     * @param account Account to check
     * @return Boolean indicating if account is pauser
     */
    function isPauser(address account) public view returns (bool) {
        return pausers.has(account);
    }

    /**
     * @dev Adds a pauser account. Is only callable by owner.
     * @param account Address to be added
     */
    function addPauser(address account) public onlyOwner {
        _addPauser(account);
    }

    /**
     * @dev Removes a pauser account. Is only callable by owner.
     * @param account Address to be removed
     */
    function removePauser(address account) public onlyOwner {
        _removePauser(account);
    }

    /** @dev Allows a privileged holder to renounce their role */
    function renouncePauser() public {
        _removePauser(msg.sender);
    }

    /** @dev Internal implementation of addPauser */
    function _addPauser(address account) internal {
        pausers.add(account);
        emit PauserAdded(account);
    }

    /** @dev Internal implementation of removePauser */
    function _removePauser(address account) internal {
        pausers.remove(account);
        emit PauserRemoved(account);
    }
}

// File: contracts/token/access/Pausable.sol

/**
 * MIT License
 *
 * Copyright (c) 2019 eToroX Labs
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

pragma solidity 0.4.24;


/**
 * @title Pausable
 * @dev Base contract which allows children to implement an emergency stop mechanism.
 */
contract Pausable is PauserRole {
    event Paused(address account);
    event Unpaused(address account);

    bool private paused_;

    constructor() internal {
        paused_ = false;
    }

    /**
     * @return true if the contract is paused, false otherwise.
     */
    function _paused() internal view returns(bool) {
        return paused_;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     */
    modifier whenNotPaused() {
        require(!paused_);
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     */
    modifier whenPaused() {
        require(paused_);
        _;
    }

    /**
     * @dev Modifier to make a function callable if a specified account is pauser.
     * @param account the address of the account to check
     */
    modifier requireIsPauser(address account) {
        require(isPauser(account));
        _;
    }

    /**
     * @dev Called by the owner to pause, triggers stopped state
     * @param originSender the original sender of this method
     */
    function _pause(address originSender)
        internal
    {
        paused_ = true;
        emit Paused(originSender);
    }

    /**
     * @dev Called by the owner to unpause, returns to normal state
     * @param originSender the original sender of this method
     */
    function _unpause(address originSender)
        internal
    {
        paused_ = false;
        emit Unpaused(originSender);
    }
}

// File: contracts/token/access/roles/WhitelistAdminRole.sol

/**
 * MIT License
 *
 * Copyright (c) 2019 eToroX Labs
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

pragma solidity 0.4.24;



/** @title Contract managing the whitelist admin role */
contract WhitelistAdminRole is Ownable {
    using Roles for Roles.Role;

    event WhitelistAdminAdded(address indexed account);
    event WhitelistAdminRemoved(address indexed account);

    Roles.Role private whitelistAdmins;

    constructor() internal {
        _addWhitelistAdmin(msg.sender);
    }

    modifier onlyWhitelistAdmin() {
        require(isWhitelistAdmin(msg.sender), "not whitelistAdmin");
        _;
    }

    modifier requireWhitelistAdmin(address account) {
        require(isWhitelistAdmin(account), "not whitelistAdmin");
        _;
    }

    /**
     * @dev Checks if account is whitelist dmin
     * @param account Account to check
     * @return Boolean indicating if account is whitelist admin
     */
    function isWhitelistAdmin(address account) public view returns (bool) {
        return whitelistAdmins.has(account);
    }

    /**
     * @dev Adds a whitelist admin account. Is only callable by owner.
     * @param account Address to be added
     */
    function addWhitelistAdmin(address account) public onlyOwner {
        _addWhitelistAdmin(account);
    }

    /**
     * @dev Removes a whitelist admin account. Is only callable by owner.
     * @param account Address to be removed
     */
    function removeWhitelistAdmin(address account) public onlyOwner {
        _removeWhitelistAdmin(account);
    }

    /** @dev Allows a privileged holder to renounce their role */
    function renounceWhitelistAdmin() public {
        _removeWhitelistAdmin(msg.sender);
    }

    /** @dev Internal implementation of addWhitelistAdmin */
    function _addWhitelistAdmin(address account) internal {
        whitelistAdmins.add(account);
        emit WhitelistAdminAdded(account);
    }

    /** @dev Internal implementation of removeWhitelistAdmin */
    function _removeWhitelistAdmin(address account) internal {
        whitelistAdmins.remove(account);
        emit WhitelistAdminRemoved(account);
    }
}

// File: contracts/token/access/roles/BlacklistAdminRole.sol

/**
 * MIT License
 *
 * Copyright (c) 2019 eToroX Labs
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

pragma solidity 0.4.24;



/** @title Contract managing the blacklist admin role */
contract BlacklistAdminRole is Ownable {
    using Roles for Roles.Role;

    event BlacklistAdminAdded(address indexed account);
    event BlacklistAdminRemoved(address indexed account);

    Roles.Role private blacklistAdmins;

    constructor() internal {
        _addBlacklistAdmin(msg.sender);
    }

    modifier onlyBlacklistAdmin() {
        require(isBlacklistAdmin(msg.sender), "not blacklistAdmin");
        _;
    }

    modifier requireBlacklistAdmin(address account) {
        require(isBlacklistAdmin(account), "not blacklistAdmin");
        _;
    }

    /**
     * @dev Checks if account is blacklist admin
     * @param account Account to check
     * @return Boolean indicating if account is blacklist admin
     */
    function isBlacklistAdmin(address account) public view returns (bool) {
        return blacklistAdmins.has(account);
    }

    /**
     * @dev Adds a blacklist admin account. Is only callable by owner.
     * @param account Address to be added
     */
    function addBlacklistAdmin(address account) public onlyOwner {
        _addBlacklistAdmin(account);
    }

    /**
     * @dev Removes a blacklist admin account. Is only callable by owner
     * @param account Address to be removed
     */
    function removeBlacklistAdmin(address account) public onlyOwner {
        _removeBlacklistAdmin(account);
    }

    /** @dev Allows privilege holder to renounce their role */
    function renounceBlacklistAdmin() public {
        _removeBlacklistAdmin(msg.sender);
    }

    /** @dev Internal implementation of addBlacklistAdmin */
    function _addBlacklistAdmin(address account) internal {
        blacklistAdmins.add(account);
        emit BlacklistAdminAdded(account);
    }

    /** @dev Internal implementation of removeBlacklistAdmin */
    function _removeBlacklistAdmin(address account) internal {
        blacklistAdmins.remove(account);
        emit BlacklistAdminRemoved(account);
    }
}

// File: contracts/token/access/Accesslist.sol

/**
 * MIT License
 *
 * Copyright (c) 2019 eToroX Labs
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

pragma solidity 0.4.24;




/**
 * @title The Accesslist contract
 * @dev Contract that contains a whitelist and a blacklist and manages them
 */
contract Accesslist is WhitelistAdminRole, BlacklistAdminRole {
    using Roles for Roles.Role;

    event WhitelistAdded(address indexed account);
    event WhitelistRemoved(address indexed account);
    event BlacklistAdded(address indexed account);
    event BlacklistRemoved(address indexed account);

    Roles.Role private whitelist;
    Roles.Role private blacklist;

    /**
     * @dev Calls internal function _addWhitelisted
     * to add given address to whitelist
     * @param account Address to be added
     */
    function addWhitelisted(address account)
        public
        onlyWhitelistAdmin
    {
        _addWhitelisted(account);
    }

    /**
     * @dev Calls internal function _removeWhitelisted
     * to remove given address from the whitelist
     * @param account Address to be removed
     */
    function removeWhitelisted(address account)
        public
        onlyWhitelistAdmin
    {
        _removeWhitelisted(account);
    }

    /**
     * @dev Calls internal function _addBlacklisted
     * to add given address to blacklist
     * @param account Address to be added
     */
    function addBlacklisted(address account)
        public
        onlyBlacklistAdmin
    {
        _addBlacklisted(account);
    }

    /**
     * @dev Calls internal function _removeBlacklisted
     * to remove given address from blacklist
     * @param account Address to be removed
     */
    function removeBlacklisted(address account)
        public
        onlyBlacklistAdmin
    {
        _removeBlacklisted(account);
    }

    /**
     * @dev Checks to see if the given address is whitelisted
     * @param account Address to be checked
     * @return true if address is whitelisted
     */
    function isWhitelisted(address account)
        public
        view
        returns (bool)
    {
        return whitelist.has(account);
    }

    /**
     * @dev Checks to see if given address is blacklisted
     * @param account Address to be checked
     * @return true if address is blacklisted
     */
    function isBlacklisted(address account)
        public
        view
        returns (bool)
    {
        return blacklist.has(account);
    }

    /**
     * @dev Checks to see if given address is whitelisted and not blacklisted
     * @param account Address to be checked
     * @return true if address has access
     */
    function hasAccess(address account)
        public
        view
        returns (bool)
    {
        return isWhitelisted(account) && !isBlacklisted(account);
    }


    /**
     * @dev Adds given address to the whitelist
     * @param account Address to be added
     */
    function _addWhitelisted(address account) internal {
        whitelist.add(account);
        emit WhitelistAdded(account);
    }

    /**
     * @dev Removes given address to the whitelist
     * @param account Address to be removed
     */
    function _removeWhitelisted(address account) internal {
        whitelist.remove(account);
        emit WhitelistRemoved(account);
    }

    /**
     * @dev Adds given address to the blacklist
     * @param account Address to be added
     */
    function _addBlacklisted(address account) internal {
        blacklist.add(account);
        emit BlacklistAdded(account);
    }

    /**
     * @dev Removes given address to the blacklist
     * @param account Address to be removed
     */
    function _removeBlacklisted(address account) internal {
        blacklist.remove(account);
        emit BlacklistRemoved(account);
    }
}

// File: contracts/token/access/AccesslistGuarded.sol

/**
 * MIT License
 *
 * Copyright (c) 2019 eToroX Labs
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

pragma solidity 0.4.24;


/**
 * @title The AccesslistGuarded contract
 * @dev Contract containing an accesslist and
 * modifiers to ensure proper access
 */
contract AccesslistGuarded {

    Accesslist private accesslist;
    bool private whitelistEnabled;

    /**
     * @dev Constructor. Checks if the accesslist is a zero address
     * @param _accesslist The access list
     * @param _whitelistEnabled If the whitelist is enabled
     */
    constructor(
        Accesslist _accesslist,
        bool _whitelistEnabled
    )
        public
    {
        require(
            _accesslist != Accesslist(0),
            "Supplied accesslist is null"
        );
        accesslist = _accesslist;
        whitelistEnabled = _whitelistEnabled;
    }

    /**
     * @dev Modifier that requires given address
     * to be whitelisted and not blacklisted
     * @param account address to be checked
     */
    modifier requireHasAccess(address account) {
        require(hasAccess(account), "no access");
        _;
    }

    /**
     * @dev Modifier that requires the message sender
     * to be whitelisted and not blacklisted
     */
    modifier onlyHasAccess() {
        require(hasAccess(msg.sender), "no access");
        _;
    }

    /**
     * @dev Modifier that requires given address
     * to be whitelisted
     * @param account address to be checked
     */
    modifier requireWhitelisted(address account) {
        require(isWhitelisted(account), "no access");
        _;
    }

    /**
     * @dev Modifier that requires message sender
     * to be whitelisted
     */
    modifier onlyWhitelisted() {
        require(isWhitelisted(msg.sender), "no access");
        _;
    }

    /**
     * @dev Modifier that requires given address
     * to not be blacklisted
     * @param account address to be checked
     */
    modifier requireNotBlacklisted(address account) {
        require(isNotBlacklisted(account), "no access");
        _;
    }

    /**
     * @dev Modifier that requires message sender
     * to not be blacklisted
     */
    modifier onlyNotBlacklisted() {
        require(isNotBlacklisted(msg.sender), "no access");
        _;
    }

    /**
     * @dev Returns whether account has access.
     * If whitelist is enabled a whitelist check is also made,
     * otherwise it only checks for blacklisting.
     * @param account Address to be checked
     * @return true if address has access or is not blacklisted when whitelist
     * is disabled
     */
    function hasAccess(address account) public view returns (bool) {
        if (whitelistEnabled) {
            return accesslist.hasAccess(account);
        } else {
            return isNotBlacklisted(account);
        }
    }

    /**
     * @dev Returns whether account is whitelisted
     * @param account Address to be checked
     * @return true if address is whitelisted
     */
    function isWhitelisted(address account) public view returns (bool) {
        return accesslist.isWhitelisted(account);
    }

    /**
     * @dev Returns whether account is not blacklisted
     * @param account Address to be checked
     * @return true if address is not blacklisted
     */
    function isNotBlacklisted(address account) public view returns (bool) {
        return !accesslist.isBlacklisted(account);
    }
}

// File: contracts/token/access/roles/BurnerRole.sol

/**
 * MIT License
 *
 * Copyright (c) 2019 eToroX Labs
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

pragma solidity 0.4.24;



/** @title Contract managing the burner role */
contract BurnerRole is Ownable {
    using Roles for Roles.Role;

    event BurnerAdded(address indexed account);
    event BurnerRemoved(address indexed account);

    Roles.Role private burners;

    constructor() Ownable() internal {
        _addBurner(msg.sender);
    }

    modifier onlyBurner() {
        require(isBurner(msg.sender), "not burner");
        _;
    }

    modifier requireBurner(address account) {
        require(isBurner(account), "not burner");
        _;
    }

    /**
     * @dev Checks if account is burner
     * @param account Account to check
     * @return Boolean indicating if account is burner
     */
    function isBurner(address account) public view returns (bool) {
        return burners.has(account);
    }

    /**
     * @dev Adds a burner account
     * @dev Is only callable by owner
     * @param account Address to be added
     */
    function addBurner(address account) public onlyOwner {
        _addBurner(account);
    }

    /**
     * @dev Removes a burner account
     * @dev Is only callable by owner
     * @param account Address to be removed
     */
    function removeBurner(address account) public onlyOwner {
        _removeBurner(account);
    }

    /** @dev Allows a privileged holder to renounce their role */
    function renounceBurner() public {
        _removeBurner(msg.sender);
    }

    /** @dev Internal implementation of addBurner */
    function _addBurner(address account) internal {
        burners.add(account);
        emit BurnerAdded(account);
    }

    /** @dev Internal implementation of removeBurner */
    function _removeBurner(address account) internal {
        burners.remove(account);
        emit BurnerRemoved(account);
    }
}

// File: contracts/token/access/roles/MinterRole.sol

/**
 * MIT License
 *
 * Copyright (c) 2019 eToroX Labs
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

pragma solidity 0.4.24;



/** @title The minter role contract */
contract MinterRole is Ownable {
    using Roles for Roles.Role;

    event MinterAdded(address indexed account);
    event MinterRemoved(address indexed account);

    Roles.Role private minters;

    /**
     * @dev Checks if the message sender is a minter
     */
    modifier onlyMinter() {
        require(isMinter(msg.sender), "not minter");
        _;
    }

    /**
     * @dev Checks if the given address is a minter
     * @param account Address to be checked
     */
    modifier requireMinter(address account) {
        require(isMinter(account), "not minter");
        _;
    }

    /**
     * @dev Checks if given address is a minter
     * @param account Address to be checked
     * @return Is the address a minter
     */
    function isMinter(address account) public view returns (bool) {
        return minters.has(account);
    }

    /**
     * @dev Calls internal function _addMinter with the given address.
     * Can only be called by the owner.
     * @param account Address to be passed
     */
    function addMinter(address account) public onlyOwner {
        _addMinter(account);
    }

    /**
     * @dev Calls internal function _removeMinter with the given address.
     * Can only be called by the owner.
     * @param account Address to be passed
     */
    function removeMinter(address account) public onlyOwner {
        _removeMinter(account);
    }

    /**
     * @dev Calls internal function _removeMinter with message sender
     * as the parameter
     */
    function renounceMinter() public {
        _removeMinter(msg.sender);
    }

    /**
     * @dev Adds the given address to minters
     * @param account Address to be added
     */
    function _addMinter(address account) internal {
        minters.add(account);
        emit MinterAdded(account);
    }

    /**
     * @dev Removes given address from minters
     * @param account Address to be removed.
     */
    function _removeMinter(address account) internal {
        minters.remove(account);
        emit MinterRemoved(account);
    }
}

// File: contracts/token/access/RestrictedMinter.sol

/**
 * MIT License
 *
 * Copyright (c) 2019 eToroX Labs
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

pragma solidity 0.4.24;


/**
 * @title Restricted minter
 * @dev Implements the notion of a restricted minter which is only
 * able to mint to a single specified account. Only the owner may
 * change this account.
 */
contract RestrictedMinter  {

    address private mintingRecipientAccount;

    event MintingRecipientAccountChanged(address prev, address next);

    /**
     * @dev constructor. Sets minting recipient to given address
     * @param _mintingRecipientAccount address to be set to recipient
     */
    constructor(address _mintingRecipientAccount) internal {
        _changeMintingRecipient(msg.sender, _mintingRecipientAccount);
    }

    modifier requireMintingRecipient(address account) {
        require(account == mintingRecipientAccount,
                "is not mintingRecpientAccount");
        _;
    }

    /**
     * @return The current minting recipient account address
     */
    function getMintingRecipient() public view returns (address) {
        return mintingRecipientAccount;
    }

    /**
     * @dev Internal function allowing the owner to change the current minting recipient account
     * @param originSender The sender address of the request
     * @param _mintingRecipientAccount address of new minting recipient
     */
    function _changeMintingRecipient(
        address originSender,
        address _mintingRecipientAccount
    )
        internal
    {
        originSender;

        require(_mintingRecipientAccount != address(0),
                "zero minting recipient");
        address prev = mintingRecipientAccount;
        mintingRecipientAccount = _mintingRecipientAccount;
        emit MintingRecipientAccountChanged(prev, mintingRecipientAccount);
    }

}

// File: contracts/token/access/ETokenGuarded.sol

/**
 * MIT License
 *
 * Copyright (c) 2019 eToroX Labs
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

pragma solidity 0.4.24;










/**
 * @title EToken access guards
 * @dev This contract implements access guards for functions comprising
 * the EToken public API. Since these functions may be called through
 * a proxy, access checks does not rely on the implicit value of
 * msg.sender but rather on the originSender parameter which is passed
 * to the functions of this contract. The value of originSender is
 * captured from msg.sender at the initial landing-point of the
 * request.
 */
contract ETokenGuarded is
    Pausable,
    ERC20,
    UpgradeSupport,
    AccesslistGuarded,
    BurnerRole,
    MinterRole,
    RestrictedMinter
{

    modifier requireOwner(address addr) {
        require(owner() == addr, "is not owner");
        _;
    }

    /**
     * @dev Constructor
     * @param name The ERC20 detailed token name
     * @param symbol The ERC20 detailed symbol name
     * @param decimals Determines the number of decimals of this token
     * @param accesslist Address of a deployed whitelist contract
     * @param whitelistEnabled Create token with whitelist enabled
     * @param externalStorage The external storage contract.
     * Should be zero address if shouldCreateStorage is true.
     * @param initialDeployment Defines whether it should
     * create a new external storage. Should be false if
     * externalERC20Storage is defined.
     */
    constructor(
        string name,
        string symbol,
        uint8 decimals,
        Accesslist accesslist,
        bool whitelistEnabled,
        Storage externalStorage,
        address initialMintingRecipient,
        bool initialDeployment
    )
        internal
        ERC20(name, symbol, decimals, externalStorage, initialDeployment)
        AccesslistGuarded(accesslist, whitelistEnabled)
        RestrictedMinter(initialMintingRecipient)
    {

    }

    /**
     * @dev Permission enforcing wrapper around the functionality of
     * EToken.name. Also see the general documentation for this
     * contract.
     */
    function nameGuarded(address originSender)
        internal
        view
        returns(string)
    {
        // Silence warnings
        originSender;

        return _name();
    }

    /**
     * @dev Permission enforcing wrapper around the functionality of
     * EToken.symbol. Also see the general documentation for this
     * contract.
     */
    function symbolGuarded(address originSender)
        internal
        view
        returns(string)
    {
        // Silence warnings
        originSender;

        return _symbol();
    }

    /**
     * @dev Permission enforcing wrapper around the functionality of
     * EToken.decimals. Also see the general documentation for this
     * contract.
     */
    function decimalsGuarded(address originSender)
        internal
        view
        returns(uint8)
    {
        // Silence warnings
        originSender;

        return _decimals();
    }

    /**
     * @dev Permission enforcing wrapper around the functionality of
     * EToken.totalSupply. Also see the general documentation for this
     * contract.
     */
    function totalSupplyGuarded(address originSender)
        internal
        view
        isEnabled
        returns(uint256)
    {
        // Silence warnings
        originSender;

        return _totalSupply();
    }

    /**
     * @dev Permission enforcing wrapper around the functionality of
     * EToken.balanceOf. Also see the general documentation for this
     * contract.
     */
    function balanceOfGuarded(address originSender, address who)
        internal
        view
        isEnabled
        returns(uint256)
    {
        // Silence warnings
        originSender;

        return _balanceOf(who);
    }

    /**
     * @dev Permission enforcing wrapper around the functionality of
     * EToken.allowance. Also see the general documentation for this
     * contract.
     */
    function allowanceGuarded(
        address originSender,
        address owner,
        address spender
    )
        internal
        view
        isEnabled
        returns(uint256)
    {
        // Silence warnings
        originSender;

        return _allowance(owner, spender);
    }

    /**
     * @dev Permission enforcing wrapper around the functionality of
     * EToken.transfer. Also see the general documentation for this
     * contract.
     */
    function transferGuarded(address originSender, address to, uint256 value)
        internal
        isEnabled
        whenNotPaused
        requireHasAccess(to)
        requireHasAccess(originSender)
        returns (bool)
    {
        _transfer(originSender, to, value);
        return true;
    }

    /**
     * @dev Permission enforcing wrapper around the functionality of
     * EToken.approve. Also see the general documentation for this
     * contract.
     */
    function approveGuarded(
        address originSender,
        address spender,
        uint256 value
    )
        internal
        isEnabled
        whenNotPaused
        requireHasAccess(spender)
        requireHasAccess(originSender)
        returns (bool)
    {
        _approve(originSender, spender, value);
        return true;
    }


    /**
     * @dev Permission enforcing wrapper around the functionality of
     * EToken.transferFrom. Also see the documentation for this
     * contract.
     */
    function transferFromGuarded(
        address originSender,
        address from,
        address to,
        uint256 value
    )
        internal
        isEnabled
        whenNotPaused
        requireHasAccess(originSender)
        requireHasAccess(from)
        requireHasAccess(to)
        returns (bool)
    {
        _transferFrom(
            originSender,
            from,
            to,
            value
        );
        return true;
    }


    /**
     * @dev Permission enforcing wrapper around the functionality of
     * EToken.increaseAllowance, Also see the general documentation
     * for this contract.
     */
    function increaseAllowanceGuarded(
        address originSender,
        address spender,
        uint256 addedValue
    )
        internal
        isEnabled
        whenNotPaused
        requireHasAccess(originSender)
        requireHasAccess(spender)
        returns (bool)
    {
        _increaseAllowance(originSender, spender, addedValue);
        return true;
    }

    /**
     * @dev Permission enforcing wrapper around the functionality of
     * EToken.decreaseAllowance. Also see the general documentation
     * for this contract.
     */
    function decreaseAllowanceGuarded(
        address originSender,
        address spender,
        uint256 subtractedValue
    )
        internal
        isEnabled
        whenNotPaused
        requireHasAccess(originSender)
        requireHasAccess(spender)
        returns (bool)  {
        _decreaseAllowance(originSender, spender, subtractedValue);
        return true;
    }

    /**
     * @dev Permission enforcing wrapper around the functionality of
     * EToken.burn. Also see the general documentation for this
     * contract.
     */
    function burnGuarded(address originSender, uint256 value)
        internal
        isEnabled
        requireBurner(originSender)
    {
        _burn(originSender, value);
    }

    /**
     * @dev Permission enforcing wrapper around the functionality of
     * EToken.burnFrom. Also see the general documentation for this
     * contract.
     */
    function burnFromGuarded(address originSender, address from, uint256 value)
        internal
        isEnabled
        requireBurner(originSender)
    {
        _burnFrom(originSender, from, value);
    }

    /**
     * @dev Permission enforcing wrapper around the functionality of
     * EToken.mint. Also see the general documentation for this
     * contract.
     */
    function mintGuarded(address originSender, address to, uint256 value)
        internal
        isEnabled
        requireMinter(originSender)
        requireMintingRecipient(to)
        returns (bool success)
    {
        // Silence warnings
        originSender;

        _mint(to, value);
        return true;
    }

    /**
     * @dev Permission enforcing wrapper around the functionality of
     * EToken.changeMintingRecipient. Also see the general
     * documentation for this contract.
     */
    function changeMintingRecipientGuarded(
        address originSender,
        address mintingRecip
    )
        internal
        isEnabled
        requireOwner(originSender)
    {
        _changeMintingRecipient(originSender, mintingRecip);
    }

    /**
     * @dev Permission enforcing wrapper around the functionality of
     * EToken.pause. Also see the general documentation for this
     * contract.
     */
    function pauseGuarded(address originSender)
        internal
        isEnabled
        requireIsPauser(originSender)
        whenNotPaused
    {
        _pause(originSender);
    }

    /**
     * @dev Permission enforcing wrapper around the functionality of
     * EToken.unpause. Also see the general documentation for this
     * contract.
     */
    function unpauseGuarded(address originSender)
        internal
        isEnabled
        requireIsPauser(originSender)
        whenPaused
    {
        _unpause(originSender);
    }

    /**
     * @dev Permission enforcing wrapper around the functionality of
     * EToken.paused. Also see the general documentation for this
     * contract.
     */
    function pausedGuarded(address originSender)
        internal
        view
        isEnabled
        returns (bool)
    {
        // Silence warnings
        originSender;
        return _paused();
    }
}

// File: contracts/token/ETokenProxy.sol

/**
 * MIT License
 *
 * Copyright (c) 2019 eToroX Labs
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

pragma solidity 0.4.24;




/**
 * @title EToken upgradability proxy
 * For every call received the following takes place:
 * If this token is upgraded, all calls are forwarded to the proxy
 * interface of the new contract thereby forming a chain of proxy
 * calls.
 * If this token is not upgraded, that is, it is the most recent
 * generation of ETokens, then calls are forwarded directly to the
 * ETokenGuarded interface which performs access
 */
contract ETokenProxy is IETokenProxy, ETokenGuarded {

    /**
     * @dev Constructor
     * @param name The ERC20 detailed token name
     * @param symbol The ERC20 detailed symbol name
     * @param decimals Determines the number of decimals of this token
     * @param accesslist Address of a deployed whitelist contract
     * @param whitelistEnabled Create token with whitelist enabled
     * @param externalStorage The external storage contract.
     * Should be zero address if shouldCreateStorage is true.
     * @param initialDeployment Set to true if this is the initial deployment of
     * the token. If true it automtically creates a new ExternalERC20Storage.
     * Also, it acts as a confirmation of intention which interlocks
     * upgradedFrom as follows: If initialDeployment is true, then
     * upgradedFrom must be the zero address. Otherwise, upgradedFrom must not
     * be the zero address. The same applies to externalERC20Storage, which must
     * be set to the zero address if initialDeployment is true.
     * @param upgradedFrom The token contract that this contract upgrades. Set
     * to address(0) for initial deployments
     */
    constructor(
        string name,
        string symbol,
        uint8 decimals,
        Accesslist accesslist,
        bool whitelistEnabled,
        Storage externalStorage,
        address initialMintingRecipient,
        address upgradedFrom,
        bool initialDeployment
    )
        internal
        UpgradeSupport(initialDeployment, upgradedFrom)
        ETokenGuarded(
            name,
            symbol,
            decimals,
            accesslist,
            whitelistEnabled,
            externalStorage,
            initialMintingRecipient,
            initialDeployment
        )
    {

    }

    /** Like EToken.name but proxies calls as described in the
        documentation for the declaration of this contract. */
    function nameProxy(address sender)
        external
        view
        isEnabled
        onlyProxy
        returns(string)
    {
        if (isUpgraded()) {
            return getUpgradedToken().nameProxy(sender);
        } else {
            return nameGuarded(sender);
        }
    }

    /** Like EToken.symbol but proxies calls as described in the
        documentation for the declaration of this contract. */
    function symbolProxy(address sender)
        external
        view
        isEnabled
        onlyProxy
        returns(string)
    {
        if (isUpgraded()) {
            return getUpgradedToken().symbolProxy(sender);
        } else {
            return symbolGuarded(sender);
        }
    }

    /** Like EToken.decimals but proxies calls as described in the
        documentation for the declaration of this contract. */
    function decimalsProxy(address sender)
        external
        view
        isEnabled
        onlyProxy
        returns(uint8)
    {
        if (isUpgraded()) {
            return getUpgradedToken().decimalsProxy(sender);
        } else {
            return decimalsGuarded(sender);
        }
    }

    /** Like EToken.symbol but proxies calls as described in the
        documentation for the declaration of this contract. */
    function totalSupplyProxy(address sender)
        external
        view
        isEnabled
        onlyProxy
        returns (uint256)
    {
        if (isUpgraded()) {
            return getUpgradedToken().totalSupplyProxy(sender);
        } else {
            return totalSupplyGuarded(sender);
        }
    }

    /** Like EToken.symbol but proxies calls as described in the
        documentation for the declaration of this contract. */
    function balanceOfProxy(address sender, address who)
        external
        view
        isEnabled
        onlyProxy
        returns (uint256)
    {
        if (isUpgraded()) {
            return getUpgradedToken().balanceOfProxy(sender, who);
        } else {
            return balanceOfGuarded(sender, who);
        }
    }

    /** Like EToken.symbol but proxies calls as described in the
        documentation for the declaration of this contract. */
    function allowanceProxy(address sender, address owner, address spender)
        external
        view
        isEnabled
        onlyProxy
        returns (uint256)
    {
        if (isUpgraded()) {
            return getUpgradedToken().allowanceProxy(sender, owner, spender);
        } else {
            return allowanceGuarded(sender, owner, spender);
        }
    }


    /** Like EToken.symbol but proxies calls as described in the
        documentation for the declaration of this contract. */
    function transferProxy(address sender, address to, uint256 value)
        external
        isEnabled
        onlyProxy
        returns (bool)
    {
        if (isUpgraded()) {
            return getUpgradedToken().transferProxy(sender, to, value);
        } else {
            return transferGuarded(sender, to, value);
        }

    }

    /** Like EToken.symbol but proxies calls as described in the
        documentation for the declaration of this contract. */
    function approveProxy(address sender, address spender, uint256 value)
        external
        isEnabled
        onlyProxy
        returns (bool)
    {

        if (isUpgraded()) {
            return getUpgradedToken().approveProxy(sender, spender, value);
        } else {
            return approveGuarded(sender, spender, value);
        }
    }

    /** Like EToken.symbol but proxies calls as described in the
        documentation for the declaration of this contract. */
    function transferFromProxy(
        address sender,
        address from,
        address to,
        uint256 value
    )
        external
        isEnabled
        onlyProxy
        returns (bool)
    {
        if (isUpgraded()) {
            getUpgradedToken().transferFromProxy(
                sender,
                from,
                to,
                value
            );
        } else {
            transferFromGuarded(
                sender,
                from,
                to,
                value
            );
        }
    }

    /** Like EToken. but proxies calls as described in the
        documentation for the declaration of this contract. */
    function mintProxy(address sender, address to, uint256 value)
        external
        isEnabled
        onlyProxy
        returns (bool)
    {
        if (isUpgraded()) {
            return getUpgradedToken().mintProxy(sender, to, value);
        } else {
            return mintGuarded(sender, to, value);
        }
    }

    /** Like EToken.changeMintingRecipient but proxies calls as
        described in the documentation for the declaration of this
        contract. */
    function changeMintingRecipientProxy(address sender,
                                         address mintingRecip)
        external
        isEnabled
        onlyProxy
    {
        if (isUpgraded()) {
            getUpgradedToken().changeMintingRecipientProxy(sender, mintingRecip);
        } else {
            changeMintingRecipientGuarded(sender, mintingRecip);
        }
    }

    /** Like EToken.burn but proxies calls as described in the
        documentation for the declaration of this contract. */
    function burnProxy(address sender, uint256 value)
        external
        isEnabled
        onlyProxy
    {
        if (isUpgraded()) {
            getUpgradedToken().burnProxy(sender, value);
        } else {
            burnGuarded(sender, value);
        }
    }

    /** Like EToken.burnFrom but proxies calls as described in the
        documentation for the declaration of this contract. */
    function burnFromProxy(address sender, address from, uint256 value)
        external
        isEnabled
        onlyProxy
    {
        if (isUpgraded()) {
            getUpgradedToken().burnFromProxy(sender, from, value);
        } else {
            burnFromGuarded(sender, from, value);
        }
    }

    /** Like EToken.increaseAllowance but proxies calls as described
        in the documentation for the declaration of this contract. */
    function increaseAllowanceProxy(
        address sender,
        address spender,
        uint addedValue
    )
        external
        isEnabled
        onlyProxy
        returns (bool)
    {
        if (isUpgraded()) {
            return getUpgradedToken().increaseAllowanceProxy(
                sender, spender, addedValue);
        } else {
            return increaseAllowanceGuarded(sender, spender, addedValue);
        }
    }

    /** Like EToken.decreaseAllowance but proxies calls as described
        in the documentation for the declaration of this contract. */
    function decreaseAllowanceProxy(
        address sender,
        address spender,
        uint subtractedValue
    )
        external
        isEnabled
        onlyProxy
        returns (bool)
    {
        if (isUpgraded()) {
            return getUpgradedToken().decreaseAllowanceProxy(
                sender, spender, subtractedValue);
        } else {
            return decreaseAllowanceGuarded(sender, spender, subtractedValue);
        }
    }

    /** Like EToken.pause but proxies calls as described
        in the documentation for the declaration of this contract. */
    function pauseProxy(address sender)
        external
        isEnabled
        onlyProxy
    {
        if (isUpgraded()) {
            getUpgradedToken().pauseProxy(sender);
        } else {
            pauseGuarded(sender);
        }
    }

    /** Like EToken.unpause but proxies calls as described
        in the documentation for the declaration of this contract. */
    function unpauseProxy(address sender)
        external
        isEnabled
        onlyProxy
    {
        if (isUpgraded()) {
            getUpgradedToken().unpauseProxy(sender);
        } else {
            unpauseGuarded(sender);
        }
    }

    /** Like EToken.paused but proxies calls as described
        in the documentation for the declaration of this contract. */
    function pausedProxy(address sender)
        external
        view
        isEnabled
        onlyProxy
        returns (bool)
    {
        if (isUpgraded()) {
            return getUpgradedToken().pausedProxy(sender);
        } else {
            return pausedGuarded(sender);
        }
    }
}

// File: contracts/token/EToken.sol

/**
 * MIT License
 *
 * Copyright (c) 2019 eToroX Labs
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

pragma solidity 0.4.24;



/** @title Main EToken contract */
contract EToken is IEToken, ETokenProxy {

    /**
     * @param name The name of the token
     * @param symbol The symbol of the token
     * @param decimals The number of decimals of the token
     * @param accesslist Address of a deployed whitelist contract
     * @param whitelistEnabled Create token with whitelist enabled
     * @param externalStorage Address of a deployed ERC20 storage contract
     * @param initialMintingRecipient The initial minting recipient of the token
     * @param upgradedFrom The token contract that this contract upgrades. Set
     * to address(0) for initial deployments
     * @param initialDeployment Set to true if this is the initial deployment of
     * the token. If true it automtically creates a new ExternalERC20Storage.
     * Also, it acts as a confirmation of intention which interlocks
     * upgradedFrom as follows: If initialDeployment is true, then
     * upgradedFrom must be the zero address. Otherwise, upgradedFrom must not
     * be the zero address. The same applies to externalERC20Storage, which must
     * be set to the zero address if initialDeployment is true.
     */
    constructor(
        string name,
        string symbol,
        uint8 decimals,
        Accesslist accesslist,
        bool whitelistEnabled,
        Storage externalStorage,
        address initialMintingRecipient,
        address upgradedFrom,
        bool initialDeployment
    )
        public
        ETokenProxy(
            name,
            symbol,
            decimals,
            accesslist,
            whitelistEnabled,
            externalStorage,
            initialMintingRecipient,
            upgradedFrom,
            initialDeployment
        )
    {

    }

    /**
     * @dev Proxies call to new token if this token is upgraded
     * @return the name of the token.
     */
    function name() public view returns(string) {
        if (isUpgraded()) {
            return getUpgradedToken().nameProxy(msg.sender);
        } else {
            return nameGuarded(msg.sender);
        }
    }

    /**
     * @dev Proxies call to new token if this token is upgraded
     * @return the symbol of the token.
     */
    function symbol() public view returns(string) {
        if (isUpgraded()) {
            return getUpgradedToken().symbolProxy(msg.sender);
        } else {
            return symbolGuarded(msg.sender);
        }
    }

    /**
     * @return the number of decimals of the token.
     */
    function decimals() public view returns(uint8) {
        if (isUpgraded()) {
            return getUpgradedToken().decimalsProxy(msg.sender);
        } else {
            return decimalsGuarded(msg.sender);
        }
    }

    /**
     * @dev Proxies call to new token if this token is upgraded
     * @return Total number of tokens in existence
     */
    function totalSupply() public view returns (uint256) {
        if (isUpgraded()) {
            return getUpgradedToken().totalSupplyProxy(msg.sender);
        } else {
            return totalSupplyGuarded(msg.sender);
        }
    }

    /**
     * @dev Gets the balance of the specified address.
     * @dev Proxies call to new token if this token is upgraded
     * @param who The address to query the balance of.
     * @return An uint256 representing the amount owned by the passed address.
     */
    function balanceOf(address who) public view returns (uint256) {
        if (isUpgraded()) {
            return getUpgradedToken().balanceOfProxy(msg.sender, who);
        } else {
            return balanceOfGuarded(msg.sender, who);
        }
    }

    /**
     * @dev Function to check the amount of tokens that an owner
     * allowed to a spender.
     * @dev Proxies call to new token if this token is upgraded
     * @param owner address The address which owns the funds.
     * @param spender address The address which will spend the funds.
     * @return A uint256 specifying the amount of tokens still available
     * for the spender.
     */
    function allowance(address owner, address spender)
        public
        view
        returns (uint256)
    {
        if (isUpgraded()) {
            return getUpgradedToken().allowanceProxy(
                msg.sender,
                owner,
                spender
            );
        } else {
            return allowanceGuarded(msg.sender, owner, spender);
        }
    }


    /**
     * @dev Transfer token for a specified address
     * @dev Proxies call to new token if this token is upgraded
     * @param to The address to transfer to.
     * @param value The amount to be transferred.
     */
    function transfer(address to, uint256 value) public returns (bool) {
        if (isUpgraded()) {
            return getUpgradedToken().transferProxy(msg.sender, to, value);
        } else {
            return transferGuarded(msg.sender, to, value);
        }
    }

    /**
     * @dev Approve the passed address to spend the specified amount
     * 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
     * @dev Proxies call to new token if this token is upgraded
     * @param spender The address which will spend the funds.
     * @param value The amount of tokens to be spent.
     */
    function approve(address spender, uint256 value) public returns (bool) {
        if (isUpgraded()) {
            return getUpgradedToken().approveProxy(msg.sender, spender, value);
        } else {
            return approveGuarded(msg.sender, spender, value);
        }
    }

    /**
     * @dev Transfer tokens from one address to another
     * @dev Proxies call to new token if this token is upgraded
     * @param from address The address which you want to send tokens from
     * @param to address The address which you want to transfer to
     * @param value uint256 the amount of tokens to be transferred
     */
    function transferFrom(address from, address to, uint256 value)
        public
        returns (bool)
    {
        if (isUpgraded()) {
            return getUpgradedToken().transferFromProxy(
                msg.sender,
                from,
                to,
                value
            );
        } else {
            return transferFromGuarded(
                msg.sender,
                from,
                to,
                value
            );
        }
    }

    /**
     * @dev Function to mint tokens
     * @dev Proxies call to new token if this token is upgraded
     * @param to The address that will receive the minted tokens.
     * @param value The amount of tokens to mint.
     * @return A boolean that indicates if the operation was successful.
     */
    function mint(address to, uint256 value) public returns (bool) {
        if (isUpgraded()) {
            return getUpgradedToken().mintProxy(msg.sender, to, value);
        } else {
            return mintGuarded(msg.sender, to, value);
        }
    }

    /**
     * @dev Burns a specific amount of tokens.
     * @dev Proxies call to new token if this token is upgraded
     * @param value The amount of token to be burned.
     */
    function burn(uint256 value) public {
        if (isUpgraded()) {
            getUpgradedToken().burnProxy(msg.sender, value);
        } else {
            burnGuarded(msg.sender, value);
        }
    }

    /**
     * @dev Burns a specific amount of tokens from the target address
     * and decrements allowance
     * @dev Proxies call to new token if this token is upgraded
     * @param from address The address which you want to send tokens from
     * @param value uint256 The amount of token to be burned
     */
    function burnFrom(address from, uint256 value) public {
        if (isUpgraded()) {
            getUpgradedToken().burnFromProxy(msg.sender, from, value);
        } else {
            burnFromGuarded(msg.sender, from, value);
        }
    }

    /**
     * @dev Increase the amount of tokens that an owner allowed to a spender.
     * approve should be called when allowed_[_spender] == 0. To increment
     * allowed value is better to use this function to avoid 2 calls (and wait until
     * the first transaction is mined)
     * From MonolithDAO Token.sol
     * @dev Proxies call to new token if this token is upgraded
     * @param spender The address which will spend the funds.
     * @param addedValue The amount of tokens to increase the allowance by.
     */
    function increaseAllowance(
        address spender,
        uint addedValue
    )
        public
        returns (bool success)
    {
        if (isUpgraded()) {
            return getUpgradedToken().increaseAllowanceProxy(
                msg.sender,
                spender,
                addedValue
            );
        } else {
            return increaseAllowanceGuarded(msg.sender, spender, addedValue);
        }
    }

    /**
     * @dev Decrease the amount of tokens that an owner allowed to a spender.
     * approve should be called when allowed_[_spender] == 0. To decrement
     * allowed value is better to use this function to avoid 2 calls (and wait until
     * the first transaction is mined)
     * From MonolithDAO Token.sol
     * @dev Proxies call to new token if this token is upgraded
     * @param spender The address which will spend the funds.
     * @param subtractedValue The amount of tokens to decrease the allowance by.
     */
    function decreaseAllowance(
        address spender,
        uint subtractedValue
    )
        public
        returns (bool success)
    {
        if (isUpgraded()) {
            return getUpgradedToken().decreaseAllowanceProxy(
                msg.sender,
                spender,
                subtractedValue
            );
        } else {
            return super.decreaseAllowanceGuarded(
                msg.sender,
                spender,
                subtractedValue
            );
        }
    }

    /**
     * @dev Allows the owner to change the current minting recipient account
     * @param mintingRecip address of new minting recipient
     */
    function changeMintingRecipient(address mintingRecip) public {
        if (isUpgraded()) {
            getUpgradedToken().changeMintingRecipientProxy(
                msg.sender,
                mintingRecip
            );
        } else {
            changeMintingRecipientGuarded(msg.sender, mintingRecip);
        }
    }

    /**
     * Allows a pauser to pause the current token.
     */
    function pause() public {
        if (isUpgraded()) {
            getUpgradedToken().pauseProxy(msg.sender);
        } else {
            pauseGuarded(msg.sender);
        }
    }

    /**
     * Allows a pauser to unpause the current token.
     */
    function unpause() public {
        if (isUpgraded()) {
            getUpgradedToken().unpauseProxy(msg.sender);
        } else {
            unpauseGuarded(msg.sender);
        }
    }

    /**
     * @return true if the contract is paused, false otherwise.
     */
    function paused() public view returns (bool) {
        if (isUpgraded()) {
            return getUpgradedToken().pausedProxy(msg.sender);
        } else {
            return pausedGuarded(msg.sender);
        }
    }
}

Contract Security Audit

Contract ABI

[{"constant":false,"inputs":[{"name":"account","type":"address"}],"name":"removeBurner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"sender","type":"address"},{"name":"spender","type":"address"},{"name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowanceProxy","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_upgradedToken","type":"address"}],"name":"upgrade","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"mintingRecip","type":"address"}],"name":"changeMintingRecipient","outputs":[],"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":"getExternalStorage","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"sender","type":"address"},{"name":"spender","type":"address"},{"name":"value","type":"uint256"}],"name":"approveProxy","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","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,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"account","type":"address"}],"name":"removeMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"isWhitelisted","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"sender","type":"address"}],"name":"decimalsProxy","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"mint","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"sender","type":"address"}],"name":"nameProxy","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"value","type":"uint256"}],"name":"burn","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isUpgraded","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"isBurner","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getUpgradedToken","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"isPauser","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"sender","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferProxy","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"account","type":"address"}],"name":"removePauser","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renouncePauser","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"who","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"value","type":"uint256"}],"name":"burnFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"sender","type":"address"}],"name":"totalSupplyProxy","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"sender","type":"address"},{"name":"spender","type":"address"},{"name":"addedValue","type":"uint256"}],"name":"increaseAllowanceProxy","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"account","type":"address"}],"name":"addPauser","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"sender","type":"address"},{"name":"from","type":"address"},{"name":"value","type":"uint256"}],"name":"burnFromProxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"hasAccess","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"account","type":"address"}],"name":"addMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"finalizeUpgrade","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"sender","type":"address"}],"name":"pauseProxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"spender","type":"address"},{"name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"isMinter","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"sender","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"mintProxy","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"sender","type":"address"}],"name":"unpauseProxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getMintingRecipient","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"sender","type":"address"},{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"value","type":"uint256"}],"name":"transferFromProxy","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"isNotBlacklisted","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"sender","type":"address"}],"name":"pausedProxy","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"sender","type":"address"},{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowanceProxy","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"sender","type":"address"}],"name":"symbolProxy","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"sender","type":"address"},{"name":"mintingRecip","type":"address"}],"name":"changeMintingRecipientProxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"spender","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"sender","type":"address"},{"name":"value","type":"uint256"}],"name":"burnProxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceBurner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"sender","type":"address"},{"name":"who","type":"address"}],"name":"balanceOfProxy","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"account","type":"address"}],"name":"addBurner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"name","type":"string"},{"name":"symbol","type":"string"},{"name":"decimals","type":"uint8"},{"name":"accesslist","type":"address"},{"name":"whitelistEnabled","type":"bool"},{"name":"externalStorage","type":"address"},{"name":"initialMintingRecipient","type":"address"},{"name":"upgradedFrom","type":"address"},{"name":"initialDeployment","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"prev","type":"address"},{"indexed":false,"name":"next","type":"address"}],"name":"MintingRecipientAccountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"}],"name":"MinterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"}],"name":"MinterRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"}],"name":"BurnerAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"}],"name":"BurnerRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"to","type":"address"}],"name":"Upgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"upgradedFrom","type":"address"}],"name":"UpgradeFinalized","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":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"}],"name":"PauserAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"}],"name":"PauserRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]

60806040523480156200001157600080fd5b50604051620068873803806200688783398101806040528101908080518201929190602001805182019291906020018051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919050505088888888888888888888888888888888878185858b8d8c8c8c8a89336000806101000a815481600160a060020a030219169083600160a060020a031602179055506000809054906101000a9004600160a060020a0316600160a060020a03166000600160a060020a03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3620001333364010000000062000503810204565b6002805460ff19169055600160a060020a0382161580159062000154575080155b80620001705750600160a060020a038216158015620001705750805b15156200020457604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603d60248201527f43616e6e6f7420626f7468206372656174652065787465726e616c2073746f7260448201527f61676520616e6420757365207468652070726f7669646564206f6e652e000000606482015290519081900360840190fd5b84516200021990600390602088019062000718565b5083516200022f90600490602087019062000718565b506005805460ff191660ff85161790558015620002b3573330620002526200079d565b600160a060020a03928316815291166020820152604080519182900301906000f08015801562000286573d6000803e3d6000fd5b50600260016101000a815481600160a060020a030219169083600160a060020a03160217905550620002d4565b6002805461010060a860020a031916610100600160a060020a038516021790555b5050505050600160a060020a03811615801590620002f0575081155b806200030c5750600160a060020a0381161580156200030c5750815b1515620003a057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f43616e6e6f7420626f746820626520757067726164656420616e6420696e697460448201527f69616c206465706c6f796d656e742e0000000000000000000000000000000000606482015290519081900360840190fd5b811515620003ce576005805461010060b060020a031916610100600160a060020a03841602179055620003f7565b6005805460a860020a60ff02191675010000000000000000000000000000000000000000001790555b5050600160a060020a03821615156200047157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f537570706c696564206163636573736c697374206973206e756c6c0000000000604482015290519081900360640190fd5b60078054600160a060020a031916600160a060020a03939093169290921760a060020a60ff0219167401000000000000000000000000000000000000000091151591909102179055620004cd3364010000000062000555810204565b620004e23382640100000000620005a7810204565b505050505050505050505050505050505050505050505050505050620007ce565b6200051e600182640100000000620051586200068582021704565b604051600160a060020a038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b62000570600882640100000000620051586200068582021704565b604051600160a060020a038216907f86e57fd2b90329052917118de7c3f521f400d439b9650deaa906a25b08b9456090600090a250565b6000600160a060020a03821615156200062157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f7a65726f206d696e74696e6720726563697069656e7400000000000000000000604482015290519081900360640190fd5b50600a8054600160a060020a03838116600160a060020a0319831617928390556040805192821680845293909116602083015280517f459b9e003f912ddab39010dc19b9e21622a1453edd934cbfe447fde61caeea869281900390910190a1505050565b600160a060020a03811615156200069b57600080fd5b620006b08282640100000000620006e0810204565b15620006bb57600080fd5b600160a060020a0316600090815260209190915260409020805460ff19166001179055565b6000600160a060020a0382161515620006f857600080fd5b50600160a060020a03166000908152602091909152604090205460ff1690565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200075b57805160ff19168380011785556200078b565b828001600101855582156200078b579182015b828111156200078b5782518255916020019190600101906200076e565b5062000799929150620007ae565b5090565b604051610ced8062005b9a83390190565b620007cb91905b80821115620007995760008155600101620007b5565b90565b6153bc80620007de6000396000f3006080604052600436106102bb5763ffffffff60e060020a6000350416630284685881146102c057806302a4e488146102e357806306fdde03146103215780630900f010146103ab578063095ea7b3146103cc5780631012c9e8146103f057806318160ddd1461041157806322a1e225146104385780632376fe701461046957806323b872dd146104935780633092afd5146104bd578063313ce567146104de57806339509351146105095780633af32abf1461052d5780633d0383b31461054e5780633f4ba83a1461056f57806340c10f1914610584578063420cc0a7146105a857806342966c68146105c957806342c80fc9146105e15780634334614a146105f6578063464c2b681461061757806346fbf68e1461062c5780634733dc8f1461064d5780635c975abb146106775780636b2c0f551461068c5780636ef8d66d146106ad57806370a08231146106c2578063715018a6146106e357806379cc6790146106f85780637c56d0fc1461071c57806382bcef791461073d57806382dc1ec4146107675780638456cb59146107885780638da5cb5b1461079d5780638f32d59b146107b25780639412be65146107c757806395a078e8146107f157806395d89b4114610812578063983b2d561461082757806398650275146108485780639a508c8e1461085d578063a1b0137114610872578063a457c2d714610893578063a9059cbb146108b7578063aa271e1a146108db578063af4e8308146108fc578063b07cd20a14610926578063b33dd71314610947578063b56d559a1461095c578063b745e8b11461098c578063be9bc819146109ad578063c190472e146109ce578063d784df9e146109fb578063d8a7be0614610a1c578063dd62ed3e14610a43578063de09ad5414610a6a578063e9ec9e8b14610a8e578063f2fde38b14610aa3578063f405494014610ac4578063f44637ba14610aeb575b600080fd5b3480156102cc57600080fd5b506102e1600160a060020a0360043516610b0c565b005b3480156102ef57600080fd5b5061030d600160a060020a0360043581169060243516604435610b2b565b604080519115158252519081900360200190f35b34801561032d57600080fd5b50610336610ca6565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610370578181015183820152602001610358565b50505050905090810190601f16801561039d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103b757600080fd5b506102e1600160a060020a0360043516610db6565b3480156103d857600080fd5b5061030d600160a060020a0360043516602435611103565b3480156103fc57600080fd5b506102e1600160a060020a03600435166111d4565b34801561041d57600080fd5b5061042661127b565b60408051918252519081900360200190f35b34801561044457600080fd5b5061044d611328565b60408051600160a060020a039092168252519081900360200190f35b34801561047557600080fd5b5061030d600160a060020a036004358116906024351660443561133c565b34801561049f57600080fd5b5061030d600160a060020a036004358116906024351660443561147a565b3480156104c957600080fd5b506102e1600160a060020a0360043516611518565b3480156104ea57600080fd5b506104f3611534565b6040805160ff9092168252519081900360200190f35b34801561051557600080fd5b5061030d600160a060020a03600435166024356115ae565b34801561053957600080fd5b5061030d600160a060020a0360043516611643565b34801561055a57600080fd5b506104f3600160a060020a03600435166116e2565b34801561057b57600080fd5b506102e161183d565b34801561059057600080fd5b5061030d600160a060020a03600435166024356118d4565b3480156105b457600080fd5b50610336600160a060020a0360043516611969565b3480156105d557600080fd5b506102e1600435611b1a565b3480156105ed57600080fd5b5061030d611b9b565b34801561060257600080fd5b5061030d600160a060020a0360043516611bac565b34801561062357600080fd5b5061044d611bbf565b34801561063857600080fd5b5061030d600160a060020a0360043516611bce565b34801561065957600080fd5b5061030d600160a060020a0360043581169060243516604435611be1565b34801561068357600080fd5b5061030d611d1f565b34801561069857600080fd5b506102e1600160a060020a0360043516611d99565b3480156106b957600080fd5b506102e1611db5565b3480156106ce57600080fd5b50610426600160a060020a0360043516611dbe565b3480156106ef57600080fd5b506102e1611e4b565b34801561070457600080fd5b506102e1600160a060020a0360043516602435611eb5565b34801561072857600080fd5b50610426600160a060020a0360043516611f68565b34801561074957600080fd5b5061030d600160a060020a0360043581169060243516604435612089565b34801561077357600080fd5b506102e1600160a060020a03600435166121c7565b34801561079457600080fd5b506102e16121e3565b3480156107a957600080fd5b5061044d61225b565b3480156107be57600080fd5b5061030d61226a565b3480156107d357600080fd5b506102e1600160a060020a036004358116906024351660443561227b565b3480156107fd57600080fd5b5061030d600160a060020a03600435166123d7565b34801561081e57600080fd5b5061033661246e565b34801561083357600080fd5b506102e1600160a060020a03600435166124e8565b34801561085457600080fd5b506102e1612504565b34801561086957600080fd5b506102e161250d565b34801561087e57600080fd5b506102e1600160a060020a0360043516612640565b34801561089f57600080fd5b5061030d600160a060020a036004351660243561275e565b3480156108c357600080fd5b5061030d600160a060020a03600435166024356127f3565b3480156108e757600080fd5b5061030d600160a060020a0360043516612888565b34801561090857600080fd5b5061030d600160a060020a036004358116906024351660443561289b565b34801561093257600080fd5b506102e1600160a060020a03600435166129d9565b34801561095357600080fd5b5061044d612af7565b34801561096857600080fd5b5061030d600160a060020a0360043581169060243581169060443516606435612b06565b34801561099857600080fd5b5061030d600160a060020a0360043516612c89565b3480156109b957600080fd5b5061030d600160a060020a0360043516612d27565b3480156109da57600080fd5b50610426600160a060020a0360043581169060243581169060443516612e48565b348015610a0757600080fd5b50610336600160a060020a0360043516612f87565b348015610a2857600080fd5b506102e1600160a060020a03600435811690602435166130a8565b348015610a4f57600080fd5b50610426600160a060020a03600435811690602435166131da565b348015610a7657600080fd5b506102e1600160a060020a0360043516602435613270565b348015610a9a57600080fd5b506102e1613397565b348015610aaf57600080fd5b506102e1600160a060020a03600435166133a0565b348015610ad057600080fd5b50610426600160a060020a03600435811690602435166133bc565b348015610af757600080fd5b506102e1600160a060020a03600435166134f2565b610b1461226a565b1515610b1f57600080fd5b610b288161350e565b50565b60055460009060a860020a900460ff161515610b7f576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314610bd4576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b610bdc611b9b565b15610c9157610be9611bbf565b604080517f02a4e488000000000000000000000000000000000000000000000000000000008152600160a060020a038781166004830152868116602483015260448201869052915192909116916302a4e488916064808201926020929091908290030181600087803b158015610c5e57600080fd5b505af1158015610c72573d6000803e3d6000fd5b505050506040513d6020811015610c8857600080fd5b50519050610c9f565b610c9c848484613556565b90505b9392505050565b6060610cb0611b9b565b15610da757610cbd611bbf565b600160a060020a031663420cc0a7336040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050600060405180830381600087803b158015610d1757600080fd5b505af1158015610d2b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015610d5457600080fd5b810190808051640100000000811115610d6c57600080fd5b82016020810184811115610d7f57600080fd5b8151640100000000811182820187101715610d9957600080fd5b50909450610db39350505050565b610db03361366e565b90505b90565b610dbe61226a565b1515610dc957600080fd5b610dd1611b9b565b15610e26576040805160e560020a62461bcd02815260206004820152601960248201527f546f6b656e20697320616c726561647920757067726164656400000000000000604482015290519081900360640190fd5b600160a060020a0381161515610e86576040805160e560020a62461bcd02815260206004820152601e60248201527f43616e6e6f74207570677261646520746f206e756c6c20616464726573730000604482015290519081900360640190fd5b600160a060020a038116301415610ee7576040805160e560020a62461bcd02815260206004820152601860248201527f43616e6e6f74207570677261646520746f206d7973656c660000000000000000604482015290519081900360640190fd5b610eef611328565b600160a060020a031663eeb1934e6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610f2c57600080fd5b505af1158015610f40573d6000803e3d6000fd5b505050506040513d6020811015610f5657600080fd5b50511515610fd4576040805160e560020a62461bcd02815260206004820152602c60248201527f4920646f6e2774206f776e206d792073746f726167652e20546869732077696c60448201527f6c20656e64206261646c792e0000000000000000000000000000000000000000606482015290519081900360840190fd5b6006805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038316179055611004611328565b600160a060020a0316637a1f3b2c826040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050600060405180830381600087803b15801561105e57600080fd5b505af1158015611072573d6000803e3d6000fd5b5050505080600160a060020a0316639a508c8e6040518163ffffffff1660e060020a028152600401600060405180830381600087803b1580156110b457600080fd5b505af11580156110c8573d6000803e3d6000fd5b5050604051600160a060020a03841692507fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9150600090a250565b600061110d611b9b565b156111c05761111a611bbf565b604080517f2376fe70000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a0386811660248301526044820186905291519290911691632376fe70916064808201926020929091908290030181600087803b15801561118d57600080fd5b505af11580156111a1573d6000803e3d6000fd5b505050506040513d60208110156111b757600080fd5b505190506111ce565b6111cb338484613678565b90505b92915050565b6111dc611b9b565b15611271576111e9611bbf565b604080517fd8a7be06000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a0384811660248301529151929091169163d8a7be069160448082019260009290919082900301818387803b15801561125457600080fd5b505af1158015611268573d6000803e3d6000fd5b50505050610b28565b610b283382613783565b6000611285611b9b565b1561131f57611292611bbf565b600160a060020a0316637c56d0fc336040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b1580156112ec57600080fd5b505af1158015611300573d6000803e3d6000fd5b505050506040513d602081101561131657600080fd5b50519050610db3565b610db03361384f565b6002546101009004600160a060020a031690565b60055460009060a860020a900460ff161515611390576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a031633146113e5576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b6113ed611b9b565b1561146f576113fa611bbf565b604080517f2376fe70000000000000000000000000000000000000000000000000000000008152600160a060020a03878116600483015286811660248301526044820186905291519290911691632376fe70916064808201926020929091908290030181600087803b158015610c5e57600080fd5b610c9c848484613678565b6000611484611b9b565b1561150c57611491611bbf565b604080517fb56d559a000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a0387811660248301528681166044830152606482018690529151929091169163b56d559a916084808201926020929091908290030181600087803b158015610c5e57600080fd5b610c9c338585856138ab565b61152061226a565b151561152b57600080fd5b610b2881613a14565b600061153e611b9b565b156115a55761154b611bbf565b600160a060020a0316633d0383b3336040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b1580156112ec57600080fd5b610db033613a5c565b60006115b8611b9b565b15611638576115c5611bbf565b604080517f82bcef79000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a03868116602483015260448201869052915192909116916382bcef79916064808201926020929091908290030181600087803b15801561118d57600080fd5b6111cb338484613a66565b600754604080517f3af32abf000000000000000000000000000000000000000000000000000000008152600160a060020a03848116600483015291516000939290921691633af32abf9160248082019260209290919082900301818787803b1580156116ae57600080fd5b505af11580156116c2573d6000803e3d6000fd5b505050506040513d60208110156116d857600080fd5b505190505b919050565b60055460009060a860020a900460ff161515611736576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a0316331461178b576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b611793611b9b565b1561182d576117a0611bbf565b600160a060020a0316633d0383b3836040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b1580156117fa57600080fd5b505af115801561180e573d6000803e3d6000fd5b505050506040513d602081101561182457600080fd5b505190506116dd565b61183682613a5c565b90506116dd565b611845611b9b565b156118c957611852611bbf565b600160a060020a031663b07cd20a336040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050600060405180830381600087803b1580156118ac57600080fd5b505af11580156118c0573d6000803e3d6000fd5b505050506118d2565b6118d233613b71565b565b60006118de611b9b565b1561195e576118eb611bbf565b604080517faf4e8308000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a038681166024830152604482018690529151929091169163af4e8308916064808201926020929091908290030181600087803b15801561118d57600080fd5b6111cb338484613bf1565b60055460609060a860020a900460ff1615156119bd576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314611a12576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b611a1a611b9b565b15611b1157611a27611bbf565b600160a060020a031663420cc0a7836040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050600060405180830381600087803b158015611a8157600080fd5b505af1158015611a95573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611abe57600080fd5b810190808051640100000000811115611ad657600080fd5b82016020810184811115611ae957600080fd5b8151640100000000811182820187101715611b0357600080fd5b509094506116dd9350505050565b6118368261366e565b611b22611b9b565b15611b9157611b2f611bbf565b600160a060020a031663de09ad5433836040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050600060405180830381600087803b15801561125457600080fd5b610b283382613d16565b600654600160a060020a0316151590565b60006111ce60088363ffffffff613dd716565b600654600160a060020a031690565b60006111ce60018363ffffffff613dd716565b60055460009060a860020a900460ff161515611c35576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314611c8a576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b611c92611b9b565b15611d1457611c9f611bbf565b604080517f4733dc8f000000000000000000000000000000000000000000000000000000008152600160a060020a03878116600483015286811660248301526044820186905291519290911691634733dc8f916064808201926020929091908290030181600087803b158015610c5e57600080fd5b610c9c848484613e0e565b6000611d29611b9b565b15611d9057611d36611bbf565b600160a060020a031663be9bc819336040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b1580156112ec57600080fd5b610db033613f19565b611da161226a565b1515611dac57600080fd5b610b2881613f75565b6118d233613f75565b6000611dc8611b9b565b15611e4157611dd5611bbf565b604080517ff4054940000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a0385811660248301529151929091169163f4054940916044808201926020929091908290030181600087803b1580156117fa57600080fd5b6118363383613fbd565b611e5361226a565b1515611e5e57600080fd5b60008054604051600160a060020a03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a36000805473ffffffffffffffffffffffffffffffffffffffff19169055565b611ebd611b9b565b15611f5957611eca611bbf565b604080517f9412be65000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a0385811660248301526044820185905291519290911691639412be659160648082019260009290919082900301818387803b158015611f3c57600080fd5b505af1158015611f50573d6000803e3d6000fd5b50505050611f64565b611f6433838361401a565b5050565b60055460009060a860020a900460ff161515611fbc576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314612011576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b612019611b9b565b1561208057612026611bbf565b600160a060020a0316637c56d0fc836040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b1580156117fa57600080fd5b6118368261384f565b60055460009060a860020a900460ff1615156120dd576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314612132576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b61213a611b9b565b156121bc57612147611bbf565b604080517f82bcef79000000000000000000000000000000000000000000000000000000008152600160a060020a038781166004830152868116602483015260448201869052915192909116916382bcef79916064808201926020929091908290030181600087803b158015610c5e57600080fd5b610c9c848484613a66565b6121cf61226a565b15156121da57600080fd5b610b28816140dd565b6121eb611b9b565b15612252576121f8611bbf565b600160a060020a031663a1b01371336040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050600060405180830381600087803b1580156118ac57600080fd5b6118d233614125565b600054600160a060020a031690565b600054600160a060020a0316331490565b60055460a860020a900460ff1615156122cc576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314612321576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b612329611b9b565b156123c757612336611bbf565b604080517f9412be65000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015285811660248301526044820185905291519290911691639412be659160648082019260009290919082900301818387803b1580156123aa57600080fd5b505af11580156123be573d6000803e3d6000fd5b505050506123d2565b6123d283838361401a565b505050565b60075460009074010000000000000000000000000000000000000000900460ff161561246557600754604080517f95a078e8000000000000000000000000000000000000000000000000000000008152600160a060020a038581166004830152915191909216916395a078e89160248083019260209291908290030181600087803b1580156117fa57600080fd5b61183682612c89565b6060612478611b9b565b156124df57612485611bbf565b600160a060020a031663d784df9e336040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050600060405180830381600087803b158015610d1757600080fd5b610db0336141a4565b6124f061226a565b15156124fb57600080fd5b610b28816141ae565b6118d233613a14565b6005546101009004600160a060020a03161515612599576040805160e560020a62461bcd028152602060048201526024808201527f4d7573742068617665206120636f6e747261637420746f20757067726164652060448201527f66726f6d00000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6005546101009004600160a060020a031633146125ee576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b6005805475ff000000000000000000000000000000000000000000191660a860020a17905560405133907f81a9bb8030ed4116b405800280e065110a37afb57b69948e714c97fab23475ec90600090a2565b60055460a860020a900460ff161515612691576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a031633146126e6576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b6126ee611b9b565b15612755576126fb611bbf565b600160a060020a031663a1b01371826040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050600060405180830381600087803b15801561125457600080fd5b610b2881614125565b6000612768611b9b565b156127e857612775611bbf565b604080517f02a4e488000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a03868116602483015260448201869052915192909116916302a4e488916064808201926020929091908290030181600087803b15801561118d57600080fd5b6111cb338484613556565b60006127fd611b9b565b1561287d5761280a611bbf565b604080517f4733dc8f000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a0386811660248301526044820186905291519290911691634733dc8f916064808201926020929091908290030181600087803b15801561118d57600080fd5b6111cb338484613e0e565b60006111ce60098363ffffffff613dd716565b60055460009060a860020a900460ff1615156128ef576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314612944576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b61294c611b9b565b156129ce57612959611bbf565b604080517faf4e8308000000000000000000000000000000000000000000000000000000008152600160a060020a0387811660048301528681166024830152604482018690529151929091169163af4e8308916064808201926020929091908290030181600087803b158015610c5e57600080fd5b610c9c848484613bf1565b60055460a860020a900460ff161515612a2a576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314612a7f576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b612a87611b9b565b15612aee57612a94611bbf565b600160a060020a031663b07cd20a826040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050600060405180830381600087803b15801561125457600080fd5b610b2881613b71565b600a54600160a060020a031690565b60055460009060a860020a900460ff161515612b5a576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314612baf576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b612bb7611b9b565b15612c7357612bc4611bbf565b604080517fb56d559a000000000000000000000000000000000000000000000000000000008152600160a060020a03888116600483015287811660248301528681166044830152606482018690529151929091169163b56d559a916084808201926020929091908290030181600087803b158015612c4157600080fd5b505af1158015612c55573d6000803e3d6000fd5b505050506040513d6020811015612c6b57600080fd5b50612c819050565b612c7f858585856138ab565b505b949350505050565b600754604080517ffe575a87000000000000000000000000000000000000000000000000000000008152600160a060020a0384811660048301529151600093929092169163fe575a879160248082019260209290919082900301818787803b158015612cf457600080fd5b505af1158015612d08573d6000803e3d6000fd5b505050506040513d6020811015612d1e57600080fd5b50511592915050565b60055460009060a860020a900460ff161515612d7b576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314612dd0576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b612dd8611b9b565b15612e3f57612de5611bbf565b600160a060020a031663be9bc819836040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b1580156117fa57600080fd5b61183682613f19565b60055460009060a860020a900460ff161515612e9c576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314612ef1576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b612ef9611b9b565b15612f7c57612f06611bbf565b604080517fc190472e000000000000000000000000000000000000000000000000000000008152600160a060020a038781166004830152868116602483015285811660448301529151929091169163c190472e916064808201926020929091908290030181600087803b158015610c5e57600080fd5b610c9c8484846141f6565b60055460609060a860020a900460ff161515612fdb576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314613030576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b613038611b9b565b1561309f57613045611bbf565b600160a060020a031663d784df9e836040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050600060405180830381600087803b158015611a8157600080fd5b611836826141a4565b60055460a860020a900460ff1615156130f9576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a0316331461314e576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b613156611b9b565b156131d057613163611bbf565b604080517fd8a7be06000000000000000000000000000000000000000000000000000000008152600160a060020a03858116600483015284811660248301529151929091169163d8a7be069160448082019260009290919082900301818387803b158015611f3c57600080fd5b611f648282613783565b60006131e4611b9b565b15613265576131f1611bbf565b604080517fc190472e000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a03868116602483015285811660448301529151929091169163c190472e916064808201926020929091908290030181600087803b15801561118d57600080fd5b6111cb3384846141f6565b60055460a860020a900460ff1615156132c1576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314613316576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b61331e611b9b565b1561338d5761332b611bbf565b600160a060020a031663de09ad5483836040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050600060405180830381600087803b158015611f3c57600080fd5b611f648282613d16565b6118d23361350e565b6133a861226a565b15156133b357600080fd5b610b2881614254565b60055460009060a860020a900460ff161515613410576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314613465576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b61346d611b9b565b156134e85761347a611bbf565b604080517ff4054940000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015285811660248301529151929091169163f4054940916044808201926020929091908290030181600087803b15801561118d57600080fd5b6111cb8383613fbd565b6134fa61226a565b151561350557600080fd5b610b28816142d1565b61351f60088263ffffffff61431916565b604051600160a060020a038216907f90eabbc0c667db2a5029ed6bc0f5fe9f356d11684a4ca9fcfaec0e53f12b9c8e90600090a250565b60055460009060a860020a900460ff1615156135aa576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b60025460ff16156135ba57600080fd5b836135c4816123d7565b1515613608576040805160e560020a62461bcd0281526020600482015260096024820152600080516020615371833981519152604482015290519081900360640190fd5b83613612816123d7565b1515613656576040805160e560020a62461bcd0281526020600482015260096024820152600080516020615371833981519152604482015290519081900360640190fd5b613661868686614365565b5060019695505050505050565b60606111ce6144cb565b60055460009060a860020a900460ff1615156136cc576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b60025460ff16156136dc57600080fd5b826136e6816123d7565b151561372a576040805160e560020a62461bcd0281526020600482015260096024820152600080516020615371833981519152604482015290519081900360640190fd5b84613734816123d7565b1515613778576040805160e560020a62461bcd0281526020600482015260096024820152600080516020615371833981519152604482015290519081900360640190fd5b613661868686614561565b60055460a860020a900460ff1615156137d4576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b8180600160a060020a03166137e761225b565b600160a060020a031614613845576040805160e560020a62461bcd02815260206004820152600c60248201527f6973206e6f74206f776e65720000000000000000000000000000000000000000604482015290519081900360640190fd5b6123d28383614646565b60055460009060a860020a900460ff1615156138a3576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6111ce614719565b60055460009060a860020a900460ff1615156138ff576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b60025460ff161561390f57600080fd5b84613919816123d7565b151561395d576040805160e560020a62461bcd0281526020600482015260096024820152600080516020615371833981519152604482015290519081900360640190fd5b84613967816123d7565b15156139ab576040805160e560020a62461bcd0281526020600482015260096024820152600080516020615371833981519152604482015290519081900360640190fd5b846139b5816123d7565b15156139f9576040805160e560020a62461bcd0281526020600482015260096024820152600080516020615371833981519152604482015290519081900360640190fd5b613a058888888861479f565b50600198975050505050505050565b613a2560098263ffffffff61431916565b604051600160a060020a038216907fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb6669290600090a250565b60006111ce614900565b60055460009060a860020a900460ff161515613aba576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b60025460ff1615613aca57600080fd5b83613ad4816123d7565b1515613b18576040805160e560020a62461bcd0281526020600482015260096024820152600080516020615371833981519152604482015290519081900360640190fd5b83613b22816123d7565b1515613b66576040805160e560020a62461bcd0281526020600482015260096024820152600080516020615371833981519152604482015290519081900360640190fd5b613661868686614909565b60055460a860020a900460ff161515613bc2576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b80613bcc81611bce565b1515613bd757600080fd5b60025460ff161515613be857600080fd5b611f648261499c565b60055460009060a860020a900460ff161515613c45576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b83613c4f81612888565b1515613ca5576040805160e560020a62461bcd02815260206004820152600a60248201527f6e6f74206d696e74657200000000000000000000000000000000000000000000604482015290519081900360640190fd5b600a548490600160a060020a03808316911614613d0c576040805160e560020a62461bcd02815260206004820152601d60248201527f6973206e6f74206d696e74696e675265637069656e744163636f756e74000000604482015290519081900360640190fd5b61366185856149e5565b60055460a860020a900460ff161515613d67576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b81613d7181611bac565b1515613dc7576040805160e560020a62461bcd02815260206004820152600a60248201527f6e6f74206275726e657200000000000000000000000000000000000000000000604482015290519081900360640190fd5b613dd18383614bcd565b50505050565b6000600160a060020a0382161515613dee57600080fd5b50600160a060020a03166000908152602091909152604090205460ff1690565b60055460009060a860020a900460ff161515613e62576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b60025460ff1615613e7257600080fd5b82613e7c816123d7565b1515613ec0576040805160e560020a62461bcd0281526020600482015260096024820152600080516020615371833981519152604482015290519081900360640190fd5b84613eca816123d7565b1515613f0e576040805160e560020a62461bcd0281526020600482015260096024820152600080516020615371833981519152604482015290519081900360640190fd5b613661868686614db5565b60055460009060a860020a900460ff161515613f6d576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6111ce614f30565b613f8660018263ffffffff61431916565b604051600160a060020a038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b60055460009060a860020a900460ff161515614011576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6111cb82614f39565b60055460a860020a900460ff16151561406b576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b8261407581611bac565b15156140cb576040805160e560020a62461bcd02815260206004820152600a60248201527f6e6f74206275726e657200000000000000000000000000000000000000000000604482015290519081900360640190fd5b6140d6848484614fa8565b5050505050565b6140ee60018263ffffffff61515816565b604051600160a060020a038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b60055460a860020a900460ff161515614176576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b8061418081611bce565b151561418b57600080fd5b60025460ff161561419b57600080fd5b611f64826151a6565b60606111ce6151f2565b6141bf60098263ffffffff61515816565b604051600160a060020a038216907f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f690600090a250565b60055460009060a860020a900460ff16151561424a576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b610c9c8383615253565b600160a060020a038116151561426957600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b6142e260088263ffffffff61515816565b604051600160a060020a038216907f86e57fd2b90329052917118de7c3f521f400d439b9650deaa906a25b08b9456090600090a250565b600160a060020a038116151561432e57600080fd5b6143388282613dd7565b151561434357600080fd5b600160a060020a0316600090815260209190915260409020805460ff19169055565b6000600160a060020a038316151561437c57600080fd5b600254604080517f63a97d3f000000000000000000000000000000000000000000000000000000008152600160a060020a0387811660048301528681166024830152604482018690529151610100909304909116916363a97d3f9160648082019260009290919082900301818387803b1580156143f857600080fd5b505af115801561440c573d6000803e3d6000fd5b50506002546040805160e160020a6363e3f4f5028152600160a060020a0389811660048301819052818a166024840181905293519396509450600080516020615351833981519152936101009004169163c7c7e9ea916044808201926020929091908290030181600087803b15801561448457600080fd5b505af1158015614498573d6000803e3d6000fd5b505050506040513d60208110156144ae57600080fd5b505160408051918252519081900360200190a35060019392505050565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156145575780601f1061452c57610100808354040283529160200191614557565b820191906000526020600020905b81548152906001019060200180831161453a57829003601f168201915b5050505050905090565b6000600160a060020a038316151561457857600080fd5b600254604080517f33dd1b8a000000000000000000000000000000000000000000000000000000008152600160a060020a0387811660048301528681166024830152604482018690529151610100909304909116916333dd1b8a9160648082019260009290919082900301818387803b1580156145f457600080fd5b505af1158015614608573d6000803e3d6000fd5b5050604080518581529051600160a060020a038088169450881692506000805160206153518339815191529181900360200190a35060019392505050565b6000600160a060020a03821615156146a8576040805160e560020a62461bcd02815260206004820152601660248201527f7a65726f206d696e74696e6720726563697069656e7400000000000000000000604482015290519081900360640190fd5b50600a8054600160a060020a0383811673ffffffffffffffffffffffffffffffffffffffff19831617928390556040805192821680845293909116602083015280517f459b9e003f912ddab39010dc19b9e21622a1453edd934cbfe447fde61caeea869281900390910190a1505050565b6000600260019054906101000a9004600160a060020a0316600160a060020a031663c4e41b226040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561476e57600080fd5b505af1158015614782573d6000803e3d6000fd5b505050506040513d602081101561479857600080fd5b5051905090565b600254604080517f63a97d3f000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015287811660248301526044820185905291516000936101009004909216916363a97d3f91606480820192869290919082900301818387803b15801561481c57600080fd5b505af1158015614830573d6000803e3d6000fd5b5050505061483f848484614db5565b506002546040805160e160020a6363e3f4f5028152600160a060020a0387811660048301819052818a1660248401819052935193949093600080516020615351833981519152936101009092049092169163c7c7e9ea916044808201926020929091908290030181600087803b1580156148b857600080fd5b505af11580156148cc573d6000803e3d6000fd5b505050506040513d60208110156148e257600080fd5b505160408051918252519081900360200190a3506001949350505050565b60055460ff1690565b6000600160a060020a038316151561492057600080fd5b600254604080517f26188a3f000000000000000000000000000000000000000000000000000000008152600160a060020a0387811660048301528681166024830152604482018690529151610100909304909116916326188a3f9160648082019260009290919082900301818387803b1580156143f857600080fd5b6002805460ff1916905560408051600160a060020a038316815290517f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa9181900360200190a150565b6000600160a060020a03831615156149fc57600080fd5b600254604080517fc4e41b220000000000000000000000000000000000000000000000000000000081529051610100909204600160a060020a03169163f7ea7a3d91614aa6918691859163c4e41b22916004808201926020929091908290030181600087803b158015614a6e57600080fd5b505af1158015614a82573d6000803e3d6000fd5b505050506040513d6020811015614a9857600080fd5b50519063ffffffff6152e716565b6040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b158015614adf57600080fd5b505af1158015614af3573d6000803e3d6000fd5b5050600254604080517f5b86f599000000000000000000000000000000000000000000000000000000008152600160a060020a0388811660048301526024820188905291516101009093049091169350635b86f599925060448082019260009290919082900301818387803b158015614b6b57600080fd5b505af1158015614b7f573d6000803e3d6000fd5b5050604080518581529051600160a060020a0387169350600092507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a350600192915050565b6000600160a060020a0383161515614be457600080fd5b600254604080517fc4e41b220000000000000000000000000000000000000000000000000000000081529051610100909204600160a060020a03169163f7ea7a3d91614c8e918691859163c4e41b22916004808201926020929091908290030181600087803b158015614c5657600080fd5b505af1158015614c6a573d6000803e3d6000fd5b505050506040513d6020811015614c8057600080fd5b50519063ffffffff6152f916565b6040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b158015614cc757600080fd5b505af1158015614cdb573d6000803e3d6000fd5b5050600254604080517fff056949000000000000000000000000000000000000000000000000000000008152600160a060020a038881166004830152602482018890529151610100909304909116935063ff056949925060448082019260009290919082900301818387803b158015614d5357600080fd5b505af1158015614d67573d6000803e3d6000fd5b505060408051858152905160009350600160a060020a03871692507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a350600192915050565b6000600160a060020a0383161515614dcc57600080fd5b600254604080517fff056949000000000000000000000000000000000000000000000000000000008152600160a060020a0387811660048301526024820186905291516101009093049091169163ff0569499160448082019260009290919082900301818387803b158015614e4057600080fd5b505af1158015614e54573d6000803e3d6000fd5b5050600254604080517f5b86f599000000000000000000000000000000000000000000000000000000008152600160a060020a0388811660048301526024820188905291516101009093049091169350635b86f599925060448082019260009290919082900301818387803b158015614ecc57600080fd5b505af1158015614ee0573d6000803e3d6000fd5b5050604080518581529051600160a060020a038088169450881692507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35060019392505050565b60025460ff1690565b600254604080517ff8b2cb4f000000000000000000000000000000000000000000000000000000008152600160a060020a038481166004830152915160009361010090049092169163f8b2cb4f9160248082019260209290919082900301818787803b1580156116ae57600080fd5b6002546040805160e160020a6363e3f4f5028152600160a060020a0385811660048301528681166024830152915160009361010090049092169163c7c7e9ea9160448082019260209290919082900301818787803b15801561500957600080fd5b505af115801561501d573d6000803e3d6000fd5b505050506040513d602081101561503357600080fd5b505182111561504157600080fd5b600254604080517f63a97d3f000000000000000000000000000000000000000000000000000000008152600160a060020a0386811660048301528781166024830152604482018690529151610100909304909116916363a97d3f9160648082019260009290919082900301818387803b1580156150bd57600080fd5b505af11580156150d1573d6000803e3d6000fd5b505050506150df8383614bcd565b506002546040805160e160020a6363e3f4f5028152600160a060020a038681166004830181905281891660248401819052935193949093600080516020615351833981519152936101009092049092169163c7c7e9ea916044808201926020929091908290030181600087803b15801561448457600080fd5b600160a060020a038116151561516d57600080fd5b6151778282613dd7565b1561518157600080fd5b600160a060020a0316600090815260209190915260409020805460ff19166001179055565b6002805460ff1916600117905560408051600160a060020a038316815290517f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2589181900360200190a150565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156145575780601f1061452c57610100808354040283529160200191614557565b6002546040805160e160020a6363e3f4f5028152600160a060020a0385811660048301528481166024830152915160009361010090049092169163c7c7e9ea9160448082019260209290919082900301818787803b1580156152b457600080fd5b505af11580156152c8573d6000803e3d6000fd5b505050506040513d60208110156152de57600080fd5b50519392505050565b600082820183811015610c9f57600080fd5b6000808383111561530957600080fd5b50509003905600546f6b656e2064697361626c656400000000000000000000000000000000000050726f787920697320746865206f6e6c7920616c6c6f7765642063616c6c65728c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9256e6f206163636573730000000000000000000000000000000000000000000000a165627a7a723058200e941f3968ea9425674cd4952d0caf6b6e75ef3aee7b64c8935bada1b6b089d80029608060405234801561001057600080fd5b50604051604080610ced833981016040819052815160209092015160008054600160a060020a03191633178082559192600160a060020a039290921691600080516020610ccd833981519152908290a3600160a060020a03821615156100fc57604080517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4f776e65722073686f756c64206e6f7420626520746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a038116151561019957604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f496d706c656d656e746f722073686f756c64206e6f7420626520746865207a6560448201527f726f206164647265737300000000000000000000000000000000000000000000606482015290519081900360840190fd5b6101ab826401000000006101d1810204565b60048054600160a060020a031916600160a060020a039290921691909117905550610271565b6101e2640100000000610202810204565b15156101ed57600080fd5b6101ff81640100000000610213810204565b50565b600054600160a060020a0316331490565b600160a060020a038116151561022857600080fd5b60008054604051600160a060020a0380851693921691600080516020610ccd83398151915291a360008054600160a060020a031916600160a060020a0392909216919091179055565b610a4d806102806000396000f3006080604052600436106100e55763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166326188a3f81146100ea57806333dd1b8a146101165780635b86f5991461014057806363a97d3f14610164578063715018a61461018e5780637a1f3b2c146101a35780638da5cb5b146101c45780638f32d59b146101f5578063c4e41b221461021e578063c7c7e9ea14610245578063e30443bc1461026c578063eeb1934e14610290578063f2fde38b146102a5578063f7ea7a3d146102c6578063f8b2cb4f146102de578063ff056949146102ff575b600080fd5b3480156100f657600080fd5b50610114600160a060020a0360043581169060243516604435610323565b005b34801561012257600080fd5b50610114600160a060020a03600435811690602435166044356103d6565b34801561014c57600080fd5b50610114600160a060020a036004351660243561044e565b34801561017057600080fd5b50610114600160a060020a03600435811690602435166044356104e3565b34801561019a57600080fd5b50610114610565565b3480156101af57600080fd5b50610114600160a060020a03600435166105cf565b3480156101d057600080fd5b506101d961078a565b60408051600160a060020a039092168252519081900360200190f35b34801561020157600080fd5b5061020a610799565b604080519115158252519081900360200190f35b34801561022a57600080fd5b506102336107aa565b60408051918252519081900360200190f35b34801561025157600080fd5b50610233600160a060020a03600435811690602435166107b0565b34801561027857600080fd5b50610114600160a060020a03600435166024356107db565b34801561029c57600080fd5b5061020a610843565b3480156102b157600080fd5b50610114600160a060020a0360043516610854565b3480156102d257600080fd5b50610114600435610873565b3480156102ea57600080fd5b50610233600160a060020a03600435166108c4565b34801561030b57600080fd5b50610114600160a060020a03600435166024356108df565b61032b610843565b151561036f576040805160e560020a62461bcd0281526020600482015260126024820152600080516020610a02833981519152604482015290519081900360640190fd5b600160a060020a038084166000908152600260209081526040808320938616835292905220546103a5908263ffffffff61095416565b600160a060020a03938416600090815260026020908152604080832095909616825293909352929091209190915550565b6103de610843565b1515610422576040805160e560020a62461bcd0281526020600482015260126024820152600080516020610a02833981519152604482015290519081900360640190fd5b600160a060020a0392831660009081526002602090815260408083209490951682529290925291902055565b610456610843565b151561049a576040805160e560020a62461bcd0281526020600482015260126024820152600080516020610a02833981519152604482015290519081900360640190fd5b600160a060020a0382166000908152600160205260409020546104c3908263ffffffff61095416565b600160a060020a0390921660009081526001602052604090209190915550565b6104eb610843565b151561052f576040805160e560020a62461bcd0281526020600482015260126024820152600080516020610a02833981519152604482015290519081900360640190fd5b600160a060020a038084166000908152600260209081526040808320938616835292905220546103a5908263ffffffff61096d16565b61056d610799565b151561057857600080fd5b60008054604051600160a060020a03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a36000805473ffffffffffffffffffffffffffffffffffffffff19169055565b600081600160a060020a0381161515610632576040805160e560020a62461bcd02815260206004820152601b60248201527f45787065637465642061206e6f6e2d7a65726f20616464726573730000000000604482015290519081900360640190fd5b61063a610843565b806106485750610648610799565b151561069e576040805160e560020a62461bcd02815260206004820152601b60248201527f4973206e6f7420696d706c656d656e746f72206f72206f776e65720000000000604482015290519081900360640190fd5b600454600160a060020a038481169116141561072a576040805160e560020a62461bcd02815260206004820152602f60248201527f43616e6e6f74207472616e7366657220746f2073616d6520696d706c656d656e60448201527f746f72206173206578697374696e670000000000000000000000000000000000606482015290519081900360840190fd5b60048054600160a060020a0385811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116935083907f385a1f149ec7287fc5dfa9518eac63290878f4dcee968f0b75fd0931360b272290600090a3505050565b600054600160a060020a031690565b600054600160a060020a0316331490565b60035490565b600160a060020a03918216600090815260026020908152604080832093909416825291909152205490565b6107e3610843565b1515610827576040805160e560020a62461bcd0281526020600482015260126024820152600080516020610a02833981519152604482015290519081900360640190fd5b600160a060020a03909116600090815260016020526040902055565b600454600160a060020a0316331490565b61085c610799565b151561086757600080fd5b61087081610984565b50565b61087b610843565b15156108bf576040805160e560020a62461bcd0281526020600482015260126024820152600080516020610a02833981519152604482015290519081900360640190fd5b600355565b600160a060020a031660009081526001602052604090205490565b6108e7610843565b151561092b576040805160e560020a62461bcd0281526020600482015260126024820152600080516020610a02833981519152604482015290519081900360640190fd5b600160a060020a0382166000908152600160205260409020546104c3908263ffffffff61096d16565b60008282018381101561096657600080fd5b9392505050565b6000808383111561097d57600080fd5b5050900390565b600160a060020a038116151561099957600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a039290921691909117905556004973206e6f7420696d706c656d656e746f720000000000000000000000000000a165627a7a723058201e438fd2c48222a90e73a06e76b9d5a1b28c95683278a0b4b340a3fa4a5a5aba00298be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000120000000000000000000000005b3617771315ac88d120d27426a752130c9a62d8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001e65feadd70c2dbffc91c8ec0e282fcf3e4783cb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000c65546f726f2053696c76657200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004534c565800000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106102bb5763ffffffff60e060020a6000350416630284685881146102c057806302a4e488146102e357806306fdde03146103215780630900f010146103ab578063095ea7b3146103cc5780631012c9e8146103f057806318160ddd1461041157806322a1e225146104385780632376fe701461046957806323b872dd146104935780633092afd5146104bd578063313ce567146104de57806339509351146105095780633af32abf1461052d5780633d0383b31461054e5780633f4ba83a1461056f57806340c10f1914610584578063420cc0a7146105a857806342966c68146105c957806342c80fc9146105e15780634334614a146105f6578063464c2b681461061757806346fbf68e1461062c5780634733dc8f1461064d5780635c975abb146106775780636b2c0f551461068c5780636ef8d66d146106ad57806370a08231146106c2578063715018a6146106e357806379cc6790146106f85780637c56d0fc1461071c57806382bcef791461073d57806382dc1ec4146107675780638456cb59146107885780638da5cb5b1461079d5780638f32d59b146107b25780639412be65146107c757806395a078e8146107f157806395d89b4114610812578063983b2d561461082757806398650275146108485780639a508c8e1461085d578063a1b0137114610872578063a457c2d714610893578063a9059cbb146108b7578063aa271e1a146108db578063af4e8308146108fc578063b07cd20a14610926578063b33dd71314610947578063b56d559a1461095c578063b745e8b11461098c578063be9bc819146109ad578063c190472e146109ce578063d784df9e146109fb578063d8a7be0614610a1c578063dd62ed3e14610a43578063de09ad5414610a6a578063e9ec9e8b14610a8e578063f2fde38b14610aa3578063f405494014610ac4578063f44637ba14610aeb575b600080fd5b3480156102cc57600080fd5b506102e1600160a060020a0360043516610b0c565b005b3480156102ef57600080fd5b5061030d600160a060020a0360043581169060243516604435610b2b565b604080519115158252519081900360200190f35b34801561032d57600080fd5b50610336610ca6565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610370578181015183820152602001610358565b50505050905090810190601f16801561039d5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156103b757600080fd5b506102e1600160a060020a0360043516610db6565b3480156103d857600080fd5b5061030d600160a060020a0360043516602435611103565b3480156103fc57600080fd5b506102e1600160a060020a03600435166111d4565b34801561041d57600080fd5b5061042661127b565b60408051918252519081900360200190f35b34801561044457600080fd5b5061044d611328565b60408051600160a060020a039092168252519081900360200190f35b34801561047557600080fd5b5061030d600160a060020a036004358116906024351660443561133c565b34801561049f57600080fd5b5061030d600160a060020a036004358116906024351660443561147a565b3480156104c957600080fd5b506102e1600160a060020a0360043516611518565b3480156104ea57600080fd5b506104f3611534565b6040805160ff9092168252519081900360200190f35b34801561051557600080fd5b5061030d600160a060020a03600435166024356115ae565b34801561053957600080fd5b5061030d600160a060020a0360043516611643565b34801561055a57600080fd5b506104f3600160a060020a03600435166116e2565b34801561057b57600080fd5b506102e161183d565b34801561059057600080fd5b5061030d600160a060020a03600435166024356118d4565b3480156105b457600080fd5b50610336600160a060020a0360043516611969565b3480156105d557600080fd5b506102e1600435611b1a565b3480156105ed57600080fd5b5061030d611b9b565b34801561060257600080fd5b5061030d600160a060020a0360043516611bac565b34801561062357600080fd5b5061044d611bbf565b34801561063857600080fd5b5061030d600160a060020a0360043516611bce565b34801561065957600080fd5b5061030d600160a060020a0360043581169060243516604435611be1565b34801561068357600080fd5b5061030d611d1f565b34801561069857600080fd5b506102e1600160a060020a0360043516611d99565b3480156106b957600080fd5b506102e1611db5565b3480156106ce57600080fd5b50610426600160a060020a0360043516611dbe565b3480156106ef57600080fd5b506102e1611e4b565b34801561070457600080fd5b506102e1600160a060020a0360043516602435611eb5565b34801561072857600080fd5b50610426600160a060020a0360043516611f68565b34801561074957600080fd5b5061030d600160a060020a0360043581169060243516604435612089565b34801561077357600080fd5b506102e1600160a060020a03600435166121c7565b34801561079457600080fd5b506102e16121e3565b3480156107a957600080fd5b5061044d61225b565b3480156107be57600080fd5b5061030d61226a565b3480156107d357600080fd5b506102e1600160a060020a036004358116906024351660443561227b565b3480156107fd57600080fd5b5061030d600160a060020a03600435166123d7565b34801561081e57600080fd5b5061033661246e565b34801561083357600080fd5b506102e1600160a060020a03600435166124e8565b34801561085457600080fd5b506102e1612504565b34801561086957600080fd5b506102e161250d565b34801561087e57600080fd5b506102e1600160a060020a0360043516612640565b34801561089f57600080fd5b5061030d600160a060020a036004351660243561275e565b3480156108c357600080fd5b5061030d600160a060020a03600435166024356127f3565b3480156108e757600080fd5b5061030d600160a060020a0360043516612888565b34801561090857600080fd5b5061030d600160a060020a036004358116906024351660443561289b565b34801561093257600080fd5b506102e1600160a060020a03600435166129d9565b34801561095357600080fd5b5061044d612af7565b34801561096857600080fd5b5061030d600160a060020a0360043581169060243581169060443516606435612b06565b34801561099857600080fd5b5061030d600160a060020a0360043516612c89565b3480156109b957600080fd5b5061030d600160a060020a0360043516612d27565b3480156109da57600080fd5b50610426600160a060020a0360043581169060243581169060443516612e48565b348015610a0757600080fd5b50610336600160a060020a0360043516612f87565b348015610a2857600080fd5b506102e1600160a060020a03600435811690602435166130a8565b348015610a4f57600080fd5b50610426600160a060020a03600435811690602435166131da565b348015610a7657600080fd5b506102e1600160a060020a0360043516602435613270565b348015610a9a57600080fd5b506102e1613397565b348015610aaf57600080fd5b506102e1600160a060020a03600435166133a0565b348015610ad057600080fd5b50610426600160a060020a03600435811690602435166133bc565b348015610af757600080fd5b506102e1600160a060020a03600435166134f2565b610b1461226a565b1515610b1f57600080fd5b610b288161350e565b50565b60055460009060a860020a900460ff161515610b7f576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314610bd4576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b610bdc611b9b565b15610c9157610be9611bbf565b604080517f02a4e488000000000000000000000000000000000000000000000000000000008152600160a060020a038781166004830152868116602483015260448201869052915192909116916302a4e488916064808201926020929091908290030181600087803b158015610c5e57600080fd5b505af1158015610c72573d6000803e3d6000fd5b505050506040513d6020811015610c8857600080fd5b50519050610c9f565b610c9c848484613556565b90505b9392505050565b6060610cb0611b9b565b15610da757610cbd611bbf565b600160a060020a031663420cc0a7336040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050600060405180830381600087803b158015610d1757600080fd5b505af1158015610d2b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015610d5457600080fd5b810190808051640100000000811115610d6c57600080fd5b82016020810184811115610d7f57600080fd5b8151640100000000811182820187101715610d9957600080fd5b50909450610db39350505050565b610db03361366e565b90505b90565b610dbe61226a565b1515610dc957600080fd5b610dd1611b9b565b15610e26576040805160e560020a62461bcd02815260206004820152601960248201527f546f6b656e20697320616c726561647920757067726164656400000000000000604482015290519081900360640190fd5b600160a060020a0381161515610e86576040805160e560020a62461bcd02815260206004820152601e60248201527f43616e6e6f74207570677261646520746f206e756c6c20616464726573730000604482015290519081900360640190fd5b600160a060020a038116301415610ee7576040805160e560020a62461bcd02815260206004820152601860248201527f43616e6e6f74207570677261646520746f206d7973656c660000000000000000604482015290519081900360640190fd5b610eef611328565b600160a060020a031663eeb1934e6040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015610f2c57600080fd5b505af1158015610f40573d6000803e3d6000fd5b505050506040513d6020811015610f5657600080fd5b50511515610fd4576040805160e560020a62461bcd02815260206004820152602c60248201527f4920646f6e2774206f776e206d792073746f726167652e20546869732077696c60448201527f6c20656e64206261646c792e0000000000000000000000000000000000000000606482015290519081900360840190fd5b6006805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a038316179055611004611328565b600160a060020a0316637a1f3b2c826040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050600060405180830381600087803b15801561105e57600080fd5b505af1158015611072573d6000803e3d6000fd5b5050505080600160a060020a0316639a508c8e6040518163ffffffff1660e060020a028152600401600060405180830381600087803b1580156110b457600080fd5b505af11580156110c8573d6000803e3d6000fd5b5050604051600160a060020a03841692507fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b9150600090a250565b600061110d611b9b565b156111c05761111a611bbf565b604080517f2376fe70000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a0386811660248301526044820186905291519290911691632376fe70916064808201926020929091908290030181600087803b15801561118d57600080fd5b505af11580156111a1573d6000803e3d6000fd5b505050506040513d60208110156111b757600080fd5b505190506111ce565b6111cb338484613678565b90505b92915050565b6111dc611b9b565b15611271576111e9611bbf565b604080517fd8a7be06000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a0384811660248301529151929091169163d8a7be069160448082019260009290919082900301818387803b15801561125457600080fd5b505af1158015611268573d6000803e3d6000fd5b50505050610b28565b610b283382613783565b6000611285611b9b565b1561131f57611292611bbf565b600160a060020a0316637c56d0fc336040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b1580156112ec57600080fd5b505af1158015611300573d6000803e3d6000fd5b505050506040513d602081101561131657600080fd5b50519050610db3565b610db03361384f565b6002546101009004600160a060020a031690565b60055460009060a860020a900460ff161515611390576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a031633146113e5576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b6113ed611b9b565b1561146f576113fa611bbf565b604080517f2376fe70000000000000000000000000000000000000000000000000000000008152600160a060020a03878116600483015286811660248301526044820186905291519290911691632376fe70916064808201926020929091908290030181600087803b158015610c5e57600080fd5b610c9c848484613678565b6000611484611b9b565b1561150c57611491611bbf565b604080517fb56d559a000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a0387811660248301528681166044830152606482018690529151929091169163b56d559a916084808201926020929091908290030181600087803b158015610c5e57600080fd5b610c9c338585856138ab565b61152061226a565b151561152b57600080fd5b610b2881613a14565b600061153e611b9b565b156115a55761154b611bbf565b600160a060020a0316633d0383b3336040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b1580156112ec57600080fd5b610db033613a5c565b60006115b8611b9b565b15611638576115c5611bbf565b604080517f82bcef79000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a03868116602483015260448201869052915192909116916382bcef79916064808201926020929091908290030181600087803b15801561118d57600080fd5b6111cb338484613a66565b600754604080517f3af32abf000000000000000000000000000000000000000000000000000000008152600160a060020a03848116600483015291516000939290921691633af32abf9160248082019260209290919082900301818787803b1580156116ae57600080fd5b505af11580156116c2573d6000803e3d6000fd5b505050506040513d60208110156116d857600080fd5b505190505b919050565b60055460009060a860020a900460ff161515611736576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a0316331461178b576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b611793611b9b565b1561182d576117a0611bbf565b600160a060020a0316633d0383b3836040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b1580156117fa57600080fd5b505af115801561180e573d6000803e3d6000fd5b505050506040513d602081101561182457600080fd5b505190506116dd565b61183682613a5c565b90506116dd565b611845611b9b565b156118c957611852611bbf565b600160a060020a031663b07cd20a336040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050600060405180830381600087803b1580156118ac57600080fd5b505af11580156118c0573d6000803e3d6000fd5b505050506118d2565b6118d233613b71565b565b60006118de611b9b565b1561195e576118eb611bbf565b604080517faf4e8308000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a038681166024830152604482018690529151929091169163af4e8308916064808201926020929091908290030181600087803b15801561118d57600080fd5b6111cb338484613bf1565b60055460609060a860020a900460ff1615156119bd576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314611a12576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b611a1a611b9b565b15611b1157611a27611bbf565b600160a060020a031663420cc0a7836040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050600060405180830381600087803b158015611a8157600080fd5b505af1158015611a95573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015611abe57600080fd5b810190808051640100000000811115611ad657600080fd5b82016020810184811115611ae957600080fd5b8151640100000000811182820187101715611b0357600080fd5b509094506116dd9350505050565b6118368261366e565b611b22611b9b565b15611b9157611b2f611bbf565b600160a060020a031663de09ad5433836040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050600060405180830381600087803b15801561125457600080fd5b610b283382613d16565b600654600160a060020a0316151590565b60006111ce60088363ffffffff613dd716565b600654600160a060020a031690565b60006111ce60018363ffffffff613dd716565b60055460009060a860020a900460ff161515611c35576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314611c8a576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b611c92611b9b565b15611d1457611c9f611bbf565b604080517f4733dc8f000000000000000000000000000000000000000000000000000000008152600160a060020a03878116600483015286811660248301526044820186905291519290911691634733dc8f916064808201926020929091908290030181600087803b158015610c5e57600080fd5b610c9c848484613e0e565b6000611d29611b9b565b15611d9057611d36611bbf565b600160a060020a031663be9bc819336040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b1580156112ec57600080fd5b610db033613f19565b611da161226a565b1515611dac57600080fd5b610b2881613f75565b6118d233613f75565b6000611dc8611b9b565b15611e4157611dd5611bbf565b604080517ff4054940000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a0385811660248301529151929091169163f4054940916044808201926020929091908290030181600087803b1580156117fa57600080fd5b6118363383613fbd565b611e5361226a565b1515611e5e57600080fd5b60008054604051600160a060020a03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a36000805473ffffffffffffffffffffffffffffffffffffffff19169055565b611ebd611b9b565b15611f5957611eca611bbf565b604080517f9412be65000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a0385811660248301526044820185905291519290911691639412be659160648082019260009290919082900301818387803b158015611f3c57600080fd5b505af1158015611f50573d6000803e3d6000fd5b50505050611f64565b611f6433838361401a565b5050565b60055460009060a860020a900460ff161515611fbc576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314612011576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b612019611b9b565b1561208057612026611bbf565b600160a060020a0316637c56d0fc836040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b1580156117fa57600080fd5b6118368261384f565b60055460009060a860020a900460ff1615156120dd576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314612132576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b61213a611b9b565b156121bc57612147611bbf565b604080517f82bcef79000000000000000000000000000000000000000000000000000000008152600160a060020a038781166004830152868116602483015260448201869052915192909116916382bcef79916064808201926020929091908290030181600087803b158015610c5e57600080fd5b610c9c848484613a66565b6121cf61226a565b15156121da57600080fd5b610b28816140dd565b6121eb611b9b565b15612252576121f8611bbf565b600160a060020a031663a1b01371336040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050600060405180830381600087803b1580156118ac57600080fd5b6118d233614125565b600054600160a060020a031690565b600054600160a060020a0316331490565b60055460a860020a900460ff1615156122cc576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314612321576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b612329611b9b565b156123c757612336611bbf565b604080517f9412be65000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015285811660248301526044820185905291519290911691639412be659160648082019260009290919082900301818387803b1580156123aa57600080fd5b505af11580156123be573d6000803e3d6000fd5b505050506123d2565b6123d283838361401a565b505050565b60075460009074010000000000000000000000000000000000000000900460ff161561246557600754604080517f95a078e8000000000000000000000000000000000000000000000000000000008152600160a060020a038581166004830152915191909216916395a078e89160248083019260209291908290030181600087803b1580156117fa57600080fd5b61183682612c89565b6060612478611b9b565b156124df57612485611bbf565b600160a060020a031663d784df9e336040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050600060405180830381600087803b158015610d1757600080fd5b610db0336141a4565b6124f061226a565b15156124fb57600080fd5b610b28816141ae565b6118d233613a14565b6005546101009004600160a060020a03161515612599576040805160e560020a62461bcd028152602060048201526024808201527f4d7573742068617665206120636f6e747261637420746f20757067726164652060448201527f66726f6d00000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6005546101009004600160a060020a031633146125ee576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b6005805475ff000000000000000000000000000000000000000000191660a860020a17905560405133907f81a9bb8030ed4116b405800280e065110a37afb57b69948e714c97fab23475ec90600090a2565b60055460a860020a900460ff161515612691576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a031633146126e6576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b6126ee611b9b565b15612755576126fb611bbf565b600160a060020a031663a1b01371826040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050600060405180830381600087803b15801561125457600080fd5b610b2881614125565b6000612768611b9b565b156127e857612775611bbf565b604080517f02a4e488000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a03868116602483015260448201869052915192909116916302a4e488916064808201926020929091908290030181600087803b15801561118d57600080fd5b6111cb338484613556565b60006127fd611b9b565b1561287d5761280a611bbf565b604080517f4733dc8f000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a0386811660248301526044820186905291519290911691634733dc8f916064808201926020929091908290030181600087803b15801561118d57600080fd5b6111cb338484613e0e565b60006111ce60098363ffffffff613dd716565b60055460009060a860020a900460ff1615156128ef576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314612944576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b61294c611b9b565b156129ce57612959611bbf565b604080517faf4e8308000000000000000000000000000000000000000000000000000000008152600160a060020a0387811660048301528681166024830152604482018690529151929091169163af4e8308916064808201926020929091908290030181600087803b158015610c5e57600080fd5b610c9c848484613bf1565b60055460a860020a900460ff161515612a2a576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314612a7f576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b612a87611b9b565b15612aee57612a94611bbf565b600160a060020a031663b07cd20a826040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050600060405180830381600087803b15801561125457600080fd5b610b2881613b71565b600a54600160a060020a031690565b60055460009060a860020a900460ff161515612b5a576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314612baf576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b612bb7611b9b565b15612c7357612bc4611bbf565b604080517fb56d559a000000000000000000000000000000000000000000000000000000008152600160a060020a03888116600483015287811660248301528681166044830152606482018690529151929091169163b56d559a916084808201926020929091908290030181600087803b158015612c4157600080fd5b505af1158015612c55573d6000803e3d6000fd5b505050506040513d6020811015612c6b57600080fd5b50612c819050565b612c7f858585856138ab565b505b949350505050565b600754604080517ffe575a87000000000000000000000000000000000000000000000000000000008152600160a060020a0384811660048301529151600093929092169163fe575a879160248082019260209290919082900301818787803b158015612cf457600080fd5b505af1158015612d08573d6000803e3d6000fd5b505050506040513d6020811015612d1e57600080fd5b50511592915050565b60055460009060a860020a900460ff161515612d7b576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314612dd0576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b612dd8611b9b565b15612e3f57612de5611bbf565b600160a060020a031663be9bc819836040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b1580156117fa57600080fd5b61183682613f19565b60055460009060a860020a900460ff161515612e9c576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314612ef1576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b612ef9611b9b565b15612f7c57612f06611bbf565b604080517fc190472e000000000000000000000000000000000000000000000000000000008152600160a060020a038781166004830152868116602483015285811660448301529151929091169163c190472e916064808201926020929091908290030181600087803b158015610c5e57600080fd5b610c9c8484846141f6565b60055460609060a860020a900460ff161515612fdb576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314613030576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b613038611b9b565b1561309f57613045611bbf565b600160a060020a031663d784df9e836040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050600060405180830381600087803b158015611a8157600080fd5b611836826141a4565b60055460a860020a900460ff1615156130f9576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a0316331461314e576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b613156611b9b565b156131d057613163611bbf565b604080517fd8a7be06000000000000000000000000000000000000000000000000000000008152600160a060020a03858116600483015284811660248301529151929091169163d8a7be069160448082019260009290919082900301818387803b158015611f3c57600080fd5b611f648282613783565b60006131e4611b9b565b15613265576131f1611bbf565b604080517fc190472e000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a03868116602483015285811660448301529151929091169163c190472e916064808201926020929091908290030181600087803b15801561118d57600080fd5b6111cb3384846141f6565b60055460a860020a900460ff1615156132c1576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314613316576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b61331e611b9b565b1561338d5761332b611bbf565b600160a060020a031663de09ad5483836040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182815260200192505050600060405180830381600087803b158015611f3c57600080fd5b611f648282613d16565b6118d23361350e565b6133a861226a565b15156133b357600080fd5b610b2881614254565b60055460009060a860020a900460ff161515613410576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6005546101009004600160a060020a03163314613465576040805160e560020a62461bcd0281526020600482018190526024820152600080516020615331833981519152604482015290519081900360640190fd5b61346d611b9b565b156134e85761347a611bbf565b604080517ff4054940000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015285811660248301529151929091169163f4054940916044808201926020929091908290030181600087803b15801561118d57600080fd5b6111cb8383613fbd565b6134fa61226a565b151561350557600080fd5b610b28816142d1565b61351f60088263ffffffff61431916565b604051600160a060020a038216907f90eabbc0c667db2a5029ed6bc0f5fe9f356d11684a4ca9fcfaec0e53f12b9c8e90600090a250565b60055460009060a860020a900460ff1615156135aa576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b60025460ff16156135ba57600080fd5b836135c4816123d7565b1515613608576040805160e560020a62461bcd0281526020600482015260096024820152600080516020615371833981519152604482015290519081900360640190fd5b83613612816123d7565b1515613656576040805160e560020a62461bcd0281526020600482015260096024820152600080516020615371833981519152604482015290519081900360640190fd5b613661868686614365565b5060019695505050505050565b60606111ce6144cb565b60055460009060a860020a900460ff1615156136cc576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b60025460ff16156136dc57600080fd5b826136e6816123d7565b151561372a576040805160e560020a62461bcd0281526020600482015260096024820152600080516020615371833981519152604482015290519081900360640190fd5b84613734816123d7565b1515613778576040805160e560020a62461bcd0281526020600482015260096024820152600080516020615371833981519152604482015290519081900360640190fd5b613661868686614561565b60055460a860020a900460ff1615156137d4576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b8180600160a060020a03166137e761225b565b600160a060020a031614613845576040805160e560020a62461bcd02815260206004820152600c60248201527f6973206e6f74206f776e65720000000000000000000000000000000000000000604482015290519081900360640190fd5b6123d28383614646565b60055460009060a860020a900460ff1615156138a3576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6111ce614719565b60055460009060a860020a900460ff1615156138ff576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b60025460ff161561390f57600080fd5b84613919816123d7565b151561395d576040805160e560020a62461bcd0281526020600482015260096024820152600080516020615371833981519152604482015290519081900360640190fd5b84613967816123d7565b15156139ab576040805160e560020a62461bcd0281526020600482015260096024820152600080516020615371833981519152604482015290519081900360640190fd5b846139b5816123d7565b15156139f9576040805160e560020a62461bcd0281526020600482015260096024820152600080516020615371833981519152604482015290519081900360640190fd5b613a058888888861479f565b50600198975050505050505050565b613a2560098263ffffffff61431916565b604051600160a060020a038216907fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb6669290600090a250565b60006111ce614900565b60055460009060a860020a900460ff161515613aba576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b60025460ff1615613aca57600080fd5b83613ad4816123d7565b1515613b18576040805160e560020a62461bcd0281526020600482015260096024820152600080516020615371833981519152604482015290519081900360640190fd5b83613b22816123d7565b1515613b66576040805160e560020a62461bcd0281526020600482015260096024820152600080516020615371833981519152604482015290519081900360640190fd5b613661868686614909565b60055460a860020a900460ff161515613bc2576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b80613bcc81611bce565b1515613bd757600080fd5b60025460ff161515613be857600080fd5b611f648261499c565b60055460009060a860020a900460ff161515613c45576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b83613c4f81612888565b1515613ca5576040805160e560020a62461bcd02815260206004820152600a60248201527f6e6f74206d696e74657200000000000000000000000000000000000000000000604482015290519081900360640190fd5b600a548490600160a060020a03808316911614613d0c576040805160e560020a62461bcd02815260206004820152601d60248201527f6973206e6f74206d696e74696e675265637069656e744163636f756e74000000604482015290519081900360640190fd5b61366185856149e5565b60055460a860020a900460ff161515613d67576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b81613d7181611bac565b1515613dc7576040805160e560020a62461bcd02815260206004820152600a60248201527f6e6f74206275726e657200000000000000000000000000000000000000000000604482015290519081900360640190fd5b613dd18383614bcd565b50505050565b6000600160a060020a0382161515613dee57600080fd5b50600160a060020a03166000908152602091909152604090205460ff1690565b60055460009060a860020a900460ff161515613e62576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b60025460ff1615613e7257600080fd5b82613e7c816123d7565b1515613ec0576040805160e560020a62461bcd0281526020600482015260096024820152600080516020615371833981519152604482015290519081900360640190fd5b84613eca816123d7565b1515613f0e576040805160e560020a62461bcd0281526020600482015260096024820152600080516020615371833981519152604482015290519081900360640190fd5b613661868686614db5565b60055460009060a860020a900460ff161515613f6d576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6111ce614f30565b613f8660018263ffffffff61431916565b604051600160a060020a038216907fcd265ebaf09df2871cc7bd4133404a235ba12eff2041bb89d9c714a2621c7c7e90600090a250565b60055460009060a860020a900460ff161515614011576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b6111cb82614f39565b60055460a860020a900460ff16151561406b576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b8261407581611bac565b15156140cb576040805160e560020a62461bcd02815260206004820152600a60248201527f6e6f74206275726e657200000000000000000000000000000000000000000000604482015290519081900360640190fd5b6140d6848484614fa8565b5050505050565b6140ee60018263ffffffff61515816565b604051600160a060020a038216907f6719d08c1888103bea251a4ed56406bd0c3e69723c8a1686e017e7bbe159b6f890600090a250565b60055460a860020a900460ff161515614176576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b8061418081611bce565b151561418b57600080fd5b60025460ff161561419b57600080fd5b611f64826151a6565b60606111ce6151f2565b6141bf60098263ffffffff61515816565b604051600160a060020a038216907f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f690600090a250565b60055460009060a860020a900460ff16151561424a576040805160e560020a62461bcd02815260206004820152600e6024820152600080516020615311833981519152604482015290519081900360640190fd5b610c9c8383615253565b600160a060020a038116151561426957600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b6142e260088263ffffffff61515816565b604051600160a060020a038216907f86e57fd2b90329052917118de7c3f521f400d439b9650deaa906a25b08b9456090600090a250565b600160a060020a038116151561432e57600080fd5b6143388282613dd7565b151561434357600080fd5b600160a060020a0316600090815260209190915260409020805460ff19169055565b6000600160a060020a038316151561437c57600080fd5b600254604080517f63a97d3f000000000000000000000000000000000000000000000000000000008152600160a060020a0387811660048301528681166024830152604482018690529151610100909304909116916363a97d3f9160648082019260009290919082900301818387803b1580156143f857600080fd5b505af115801561440c573d6000803e3d6000fd5b50506002546040805160e160020a6363e3f4f5028152600160a060020a0389811660048301819052818a166024840181905293519396509450600080516020615351833981519152936101009004169163c7c7e9ea916044808201926020929091908290030181600087803b15801561448457600080fd5b505af1158015614498573d6000803e3d6000fd5b505050506040513d60208110156144ae57600080fd5b505160408051918252519081900360200190a35060019392505050565b60038054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156145575780601f1061452c57610100808354040283529160200191614557565b820191906000526020600020905b81548152906001019060200180831161453a57829003601f168201915b5050505050905090565b6000600160a060020a038316151561457857600080fd5b600254604080517f33dd1b8a000000000000000000000000000000000000000000000000000000008152600160a060020a0387811660048301528681166024830152604482018690529151610100909304909116916333dd1b8a9160648082019260009290919082900301818387803b1580156145f457600080fd5b505af1158015614608573d6000803e3d6000fd5b5050604080518581529051600160a060020a038088169450881692506000805160206153518339815191529181900360200190a35060019392505050565b6000600160a060020a03821615156146a8576040805160e560020a62461bcd02815260206004820152601660248201527f7a65726f206d696e74696e6720726563697069656e7400000000000000000000604482015290519081900360640190fd5b50600a8054600160a060020a0383811673ffffffffffffffffffffffffffffffffffffffff19831617928390556040805192821680845293909116602083015280517f459b9e003f912ddab39010dc19b9e21622a1453edd934cbfe447fde61caeea869281900390910190a1505050565b6000600260019054906101000a9004600160a060020a0316600160a060020a031663c4e41b226040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561476e57600080fd5b505af1158015614782573d6000803e3d6000fd5b505050506040513d602081101561479857600080fd5b5051905090565b600254604080517f63a97d3f000000000000000000000000000000000000000000000000000000008152600160a060020a03868116600483015287811660248301526044820185905291516000936101009004909216916363a97d3f91606480820192869290919082900301818387803b15801561481c57600080fd5b505af1158015614830573d6000803e3d6000fd5b5050505061483f848484614db5565b506002546040805160e160020a6363e3f4f5028152600160a060020a0387811660048301819052818a1660248401819052935193949093600080516020615351833981519152936101009092049092169163c7c7e9ea916044808201926020929091908290030181600087803b1580156148b857600080fd5b505af11580156148cc573d6000803e3d6000fd5b505050506040513d60208110156148e257600080fd5b505160408051918252519081900360200190a3506001949350505050565b60055460ff1690565b6000600160a060020a038316151561492057600080fd5b600254604080517f26188a3f000000000000000000000000000000000000000000000000000000008152600160a060020a0387811660048301528681166024830152604482018690529151610100909304909116916326188a3f9160648082019260009290919082900301818387803b1580156143f857600080fd5b6002805460ff1916905560408051600160a060020a038316815290517f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa9181900360200190a150565b6000600160a060020a03831615156149fc57600080fd5b600254604080517fc4e41b220000000000000000000000000000000000000000000000000000000081529051610100909204600160a060020a03169163f7ea7a3d91614aa6918691859163c4e41b22916004808201926020929091908290030181600087803b158015614a6e57600080fd5b505af1158015614a82573d6000803e3d6000fd5b505050506040513d6020811015614a9857600080fd5b50519063ffffffff6152e716565b6040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b158015614adf57600080fd5b505af1158015614af3573d6000803e3d6000fd5b5050600254604080517f5b86f599000000000000000000000000000000000000000000000000000000008152600160a060020a0388811660048301526024820188905291516101009093049091169350635b86f599925060448082019260009290919082900301818387803b158015614b6b57600080fd5b505af1158015614b7f573d6000803e3d6000fd5b5050604080518581529051600160a060020a0387169350600092507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a350600192915050565b6000600160a060020a0383161515614be457600080fd5b600254604080517fc4e41b220000000000000000000000000000000000000000000000000000000081529051610100909204600160a060020a03169163f7ea7a3d91614c8e918691859163c4e41b22916004808201926020929091908290030181600087803b158015614c5657600080fd5b505af1158015614c6a573d6000803e3d6000fd5b505050506040513d6020811015614c8057600080fd5b50519063ffffffff6152f916565b6040518263ffffffff1660e060020a02815260040180828152602001915050600060405180830381600087803b158015614cc757600080fd5b505af1158015614cdb573d6000803e3d6000fd5b5050600254604080517fff056949000000000000000000000000000000000000000000000000000000008152600160a060020a038881166004830152602482018890529151610100909304909116935063ff056949925060448082019260009290919082900301818387803b158015614d5357600080fd5b505af1158015614d67573d6000803e3d6000fd5b505060408051858152905160009350600160a060020a03871692507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a350600192915050565b6000600160a060020a0383161515614dcc57600080fd5b600254604080517fff056949000000000000000000000000000000000000000000000000000000008152600160a060020a0387811660048301526024820186905291516101009093049091169163ff0569499160448082019260009290919082900301818387803b158015614e4057600080fd5b505af1158015614e54573d6000803e3d6000fd5b5050600254604080517f5b86f599000000000000000000000000000000000000000000000000000000008152600160a060020a0388811660048301526024820188905291516101009093049091169350635b86f599925060448082019260009290919082900301818387803b158015614ecc57600080fd5b505af1158015614ee0573d6000803e3d6000fd5b5050604080518581529051600160a060020a038088169450881692507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a35060019392505050565b60025460ff1690565b600254604080517ff8b2cb4f000000000000000000000000000000000000000000000000000000008152600160a060020a038481166004830152915160009361010090049092169163f8b2cb4f9160248082019260209290919082900301818787803b1580156116ae57600080fd5b6002546040805160e160020a6363e3f4f5028152600160a060020a0385811660048301528681166024830152915160009361010090049092169163c7c7e9ea9160448082019260209290919082900301818787803b15801561500957600080fd5b505af115801561501d573d6000803e3d6000fd5b505050506040513d602081101561503357600080fd5b505182111561504157600080fd5b600254604080517f63a97d3f000000000000000000000000000000000000000000000000000000008152600160a060020a0386811660048301528781166024830152604482018690529151610100909304909116916363a97d3f9160648082019260009290919082900301818387803b1580156150bd57600080fd5b505af11580156150d1573d6000803e3d6000fd5b505050506150df8383614bcd565b506002546040805160e160020a6363e3f4f5028152600160a060020a038681166004830181905281891660248401819052935193949093600080516020615351833981519152936101009092049092169163c7c7e9ea916044808201926020929091908290030181600087803b15801561448457600080fd5b600160a060020a038116151561516d57600080fd5b6151778282613dd7565b1561518157600080fd5b600160a060020a0316600090815260209190915260409020805460ff19166001179055565b6002805460ff1916600117905560408051600160a060020a038316815290517f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2589181900360200190a150565b60048054604080516020601f60026000196101006001881615020190951694909404938401819004810282018101909252828152606093909290918301828280156145575780601f1061452c57610100808354040283529160200191614557565b6002546040805160e160020a6363e3f4f5028152600160a060020a0385811660048301528481166024830152915160009361010090049092169163c7c7e9ea9160448082019260209290919082900301818787803b1580156152b457600080fd5b505af11580156152c8573d6000803e3d6000fd5b505050506040513d60208110156152de57600080fd5b50519392505050565b600082820183811015610c9f57600080fd5b6000808383111561530957600080fd5b50509003905600546f6b656e2064697361626c656400000000000000000000000000000000000050726f787920697320746865206f6e6c7920616c6c6f7765642063616c6c65728c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9256e6f206163636573730000000000000000000000000000000000000000000000a165627a7a723058200e941f3968ea9425674cd4952d0caf6b6e75ef3aee7b64c8935bada1b6b089d80029

Swarm Source

bzzr://1e438fd2c48222a90e73a06e76b9d5a1b28c95683278a0b4b340a3fa4a5a5aba
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.