ETH Price: $3,139.59 (-0.74%)

Token

DTAETH (M-DTAETH)
 

Overview

Max Total Supply

2,124.741167397529330245 M-DTAETH

Holders

110

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
0.0326926674328701 M-DTAETH

Value
$0.00
0xdf36e4570f51256dc86ba609157dd83354e4d7b7
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
AstraMultiToken

Compiler Version
v0.4.25+commit.59dbf8f1

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2018-10-19
*/

pragma solidity ^0.4.24;

// 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 public owner;


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


  /**
   * @dev The Ownable constructor sets the original `owner` of the contract to the sender
   * account.
   */
  constructor() public {
    owner = msg.sender;
  }

  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
    require(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 OwnershipRenounced(owner);
    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/token/ERC20/ERC20Basic.sol

/**
 * @title ERC20Basic
 * @dev Simpler version of ERC20 interface
 * See https://github.com/ethereum/EIPs/issues/179
 */
contract ERC20Basic {
  function totalSupply() public view returns (uint256);
  function balanceOf(address _who) public view returns (uint256);
  function transfer(address _to, uint256 _value) public returns (bool);
  event Transfer(address indexed from, address indexed to, uint256 value);
}

// File: openzeppelin-solidity/contracts/token/ERC20/ERC20.sol

/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
contract ERC20 is ERC20Basic {
  function allowance(address _owner, address _spender)
    public view returns (uint256);

  function transferFrom(address _from, address _to, uint256 _value)
    public returns (bool);

  function approve(address _spender, uint256 _value) public returns (bool);
  event Approval(
    address indexed owner,
    address indexed spender,
    uint256 value
  );
}

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

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

  /**
  * @dev Multiplies two numbers, throws on overflow.
  */
  function mul(uint256 _a, uint256 _b) internal pure returns (uint256 c) {
    // Gas optimization: this is cheaper than asserting '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;
    }

    c = _a * _b;
    assert(c / _a == _b);
    return c;
  }

  /**
  * @dev Integer division of two numbers, truncating the quotient.
  */
  function div(uint256 _a, uint256 _b) internal pure returns (uint256) {
    // assert(_b > 0); // Solidity automatically throws 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 _a / _b;
  }

  /**
  * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
  */
  function sub(uint256 _a, uint256 _b) internal pure returns (uint256) {
    assert(_b <= _a);
    return _a - _b;
  }

  /**
  * @dev Adds two numbers, throws on overflow.
  */
  function add(uint256 _a, uint256 _b) internal pure returns (uint256 c) {
    c = _a + _b;
    assert(c >= _a);
    return c;
  }
}

// File: contracts/ext/CheckedERC20.sol

library CheckedERC20 {
    using SafeMath for uint;

    function isContract(address addr) internal view returns(bool result) {
        // solium-disable-next-line security/no-inline-assembly
        assembly {
            result := gt(extcodesize(addr), 0)
        }
    }

    function handleReturnBool() internal pure returns(bool result) {
        // solium-disable-next-line security/no-inline-assembly
        assembly {
            switch returndatasize()
            case 0 { // not a std erc20
                result := 1
            }
            case 32 { // std erc20
                returndatacopy(0, 0, 32)
                result := mload(0)
            }
            default { // anything else, should revert for safety
                revert(0, 0)
            }
        }
    }

    function handleReturnBytes32() internal pure returns(bytes32 result) {
        // solium-disable-next-line security/no-inline-assembly
        assembly {
            switch eq(returndatasize(), 32) // not a std erc20
            case 1 {
                returndatacopy(0, 0, 32)
                result := mload(0)
            }

            switch gt(returndatasize(), 32) // std erc20
            case 1 {
                returndatacopy(0, 64, 32)
                result := mload(0)
            }

            switch lt(returndatasize(), 32) // anything else, should revert for safety
            case 1 {
                revert(0, 0)
            }
        }
    }

    function asmTransfer(address token, address to, uint256 value) internal returns(bool) {
        require(isContract(token));
        // solium-disable-next-line security/no-low-level-calls
        require(token.call(bytes4(keccak256("transfer(address,uint256)")), to, value));
        return handleReturnBool();
    }

    function asmTransferFrom(address token, address from, address to, uint256 value) internal returns(bool) {
        require(isContract(token));
        // solium-disable-next-line security/no-low-level-calls
        require(token.call(bytes4(keccak256("transferFrom(address,address,uint256)")), from, to, value));
        return handleReturnBool();
    }

    function asmApprove(address token, address spender, uint256 value) internal returns(bool) {
        require(isContract(token));
        // solium-disable-next-line security/no-low-level-calls
        require(token.call(bytes4(keccak256("approve(address,uint256)")), spender, value));
        return handleReturnBool();
    }

    //

    function checkedTransfer(ERC20 token, address to, uint256 value) internal {
        if (value > 0) {
            uint256 balance = token.balanceOf(this);
            asmTransfer(token, to, value);
            require(token.balanceOf(this) == balance.sub(value), "checkedTransfer: Final balance didn't match");
        }
    }

    function checkedTransferFrom(ERC20 token, address from, address to, uint256 value) internal {
        if (value > 0) {
            uint256 toBalance = token.balanceOf(to);
            asmTransferFrom(token, from, to, value);
            require(token.balanceOf(to) == toBalance.add(value), "checkedTransfer: Final balance didn't match");
        }
    }

    //

    function asmName(address token) internal view returns(bytes32) {
        require(isContract(token));
        // solium-disable-next-line security/no-low-level-calls
        require(token.call(bytes4(keccak256("name()"))));
        return handleReturnBytes32();
    }

    function asmSymbol(address token) internal view returns(bytes32) {
        require(isContract(token));
        // solium-disable-next-line security/no-low-level-calls
        require(token.call(bytes4(keccak256("symbol()"))));
        return handleReturnBytes32();
    }
}

// File: openzeppelin-solidity/contracts/token/ERC20/BasicToken.sol

/**
 * @title Basic token
 * @dev Basic version of StandardToken, with no allowances.
 */
contract BasicToken is ERC20Basic {
  using SafeMath for uint256;

  mapping(address => uint256) internal balances;

  uint256 internal totalSupply_;

  /**
  * @dev Total number of tokens in existence
  */
  function totalSupply() public view returns (uint256) {
    return totalSupply_;
  }

  /**
  * @dev Transfer token for a specified address
  * @param _to The address to transfer to.
  * @param _value The amount to be transferred.
  */
  function transfer(address _to, uint256 _value) public returns (bool) {
    require(_value <= balances[msg.sender]);
    require(_to != address(0));

    balances[msg.sender] = balances[msg.sender].sub(_value);
    balances[_to] = balances[_to].add(_value);
    emit Transfer(msg.sender, _to, _value);
    return true;
  }

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

}

// File: openzeppelin-solidity/contracts/token/ERC20/StandardToken.sol

/**
 * @title Standard ERC20 token
 *
 * @dev Implementation of the basic standard token.
 * https://github.com/ethereum/EIPs/issues/20
 * Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
 */
contract StandardToken is ERC20, BasicToken {

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


  /**
   * @dev Transfer tokens from one address to another
   * @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)
  {
    require(_value <= balances[_from]);
    require(_value <= allowed[_from][msg.sender]);
    require(_to != address(0));

    balances[_from] = balances[_from].sub(_value);
    balances[_to] = balances[_to].add(_value);
    allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
    emit Transfer(_from, _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 _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) {
    allowed[msg.sender][_spender] = _value;
    emit Approval(msg.sender, _spender, _value);
    return true;
  }

  /**
   * @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
   )
    public
    view
    returns (uint256)
  {
    return allowed[_owner][_spender];
  }

  /**
   * @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 _spender The address which will spend the funds.
   * @param _addedValue The amount of tokens to increase the allowance by.
   */
  function increaseApproval(
    address _spender,
    uint256 _addedValue
  )
    public
    returns (bool)
  {
    allowed[msg.sender][_spender] = (
      allowed[msg.sender][_spender].add(_addedValue));
    emit Approval(msg.sender, _spender, allowed[msg.sender][_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 _spender The address which will spend the funds.
   * @param _subtractedValue The amount of tokens to decrease the allowance by.
   */
  function decreaseApproval(
    address _spender,
    uint256 _subtractedValue
  )
    public
    returns (bool)
  {
    uint256 oldValue = allowed[msg.sender][_spender];
    if (_subtractedValue >= oldValue) {
      allowed[msg.sender][_spender] = 0;
    } else {
      allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
    }
    emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
    return true;
  }

}

// File: openzeppelin-solidity/contracts/token/ERC20/DetailedERC20.sol

/**
 * @title DetailedERC20 token
 * @dev The decimals are only for visualization purposes.
 * All the operations are done using the smallest and indivisible token unit,
 * just as on Ethereum all the operations are done in wei.
 */
contract DetailedERC20 is ERC20 {
  string public name;
  string public symbol;
  uint8 public decimals;

  constructor(string _name, string _symbol, uint8 _decimals) public {
    name = _name;
    symbol = _symbol;
    decimals = _decimals;
  }
}

// File: openzeppelin-solidity/contracts/introspection/ERC165.sol

/**
 * @title ERC165
 * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
 */
interface ERC165 {

  /**
   * @notice Query if a contract implements an interface
   * @param _interfaceId The interface identifier, as specified in ERC-165
   * @dev Interface identification is specified in ERC-165. This function
   * uses less than 30,000 gas.
   */
  function supportsInterface(bytes4 _interfaceId)
    external
    view
    returns (bool);
}

// File: openzeppelin-solidity/contracts/introspection/SupportsInterfaceWithLookup.sol

/**
 * @title SupportsInterfaceWithLookup
 * @author Matt Condon (@shrugs)
 * @dev Implements ERC165 using a lookup table.
 */
contract SupportsInterfaceWithLookup is ERC165 {

  bytes4 public constant InterfaceId_ERC165 = 0x01ffc9a7;
  /**
   * 0x01ffc9a7 ===
   *   bytes4(keccak256('supportsInterface(bytes4)'))
   */

  /**
   * @dev a mapping of interface id to whether or not it's supported
   */
  mapping(bytes4 => bool) internal supportedInterfaces;

  /**
   * @dev A contract implementing SupportsInterfaceWithLookup
   * implement ERC165 itself
   */
  constructor()
    public
  {
    _registerInterface(InterfaceId_ERC165);
  }

  /**
   * @dev implement supportsInterface(bytes4) using a lookup table
   */
  function supportsInterface(bytes4 _interfaceId)
    external
    view
    returns (bool)
  {
    return supportedInterfaces[_interfaceId];
  }

  /**
   * @dev private method for registering an interface
   */
  function _registerInterface(bytes4 _interfaceId)
    internal
  {
    require(_interfaceId != 0xffffffff);
    supportedInterfaces[_interfaceId] = true;
  }
}

// File: contracts/ext/ERC1003Token.sol

contract ERC1003Caller is Ownable {
    function makeCall(address target, bytes data) external payable onlyOwner returns (bool) {
        // solium-disable-next-line security/no-call-value
        return target.call.value(msg.value)(data);
    }
}


contract ERC1003Token is ERC20 {
    ERC1003Caller private _caller = new ERC1003Caller();
    address[] internal _sendersStack;

    function caller() public view returns(ERC1003Caller) {
        return _caller;
    }

    function approveAndCall(address to, uint256 value, bytes data) public payable returns (bool) {
        _sendersStack.push(msg.sender);
        approve(to, value);
        require(_caller.makeCall.value(msg.value)(to, data));
        _sendersStack.length -= 1;
        return true;
    }

    function transferAndCall(address to, uint256 value, bytes data) public payable returns (bool) {
        transfer(to, value);
        require(_caller.makeCall.value(msg.value)(to, data));
        return true;
    }

    function transferFrom(address from, address to, uint256 value) public returns (bool) {
        address spender = (from != address(_caller)) ? from : _sendersStack[_sendersStack.length - 1];
        return super.transferFrom(spender, to, value);
    }
}

// File: contracts/interface/IBasicMultiToken.sol

contract IBasicMultiToken is ERC20 {
    event Bundle(address indexed who, address indexed beneficiary, uint256 value);
    event Unbundle(address indexed who, address indexed beneficiary, uint256 value);

    function tokensCount() public view returns(uint256);
    function tokens(uint i) public view returns(ERC20);
    function bundlingEnabled() public view returns(bool);
    
    function bundleFirstTokens(address _beneficiary, uint256 _amount, uint256[] _tokenAmounts) public;
    function bundle(address _beneficiary, uint256 _amount) public;

    function unbundle(address _beneficiary, uint256 _value) public;
    function unbundleSome(address _beneficiary, uint256 _value, ERC20[] _tokens) public;

    // Owner methods
    function disableBundling() public;
    function enableBundling() public;

    bytes4 public constant InterfaceId_IBasicMultiToken = 0xd5c368b6;
	  /**
	   * 0xd5c368b6 ===
	   *   bytes4(keccak256('tokensCount()')) ^
	   *   bytes4(keccak256('tokens(uint256)')) ^
       *   bytes4(keccak256('bundlingEnabled()')) ^
       *   bytes4(keccak256('bundleFirstTokens(address,uint256,uint256[])')) ^
       *   bytes4(keccak256('bundle(address,uint256)')) ^
       *   bytes4(keccak256('unbundle(address,uint256)')) ^
       *   bytes4(keccak256('unbundleSome(address,uint256,address[])')) ^
       *   bytes4(keccak256('disableBundling()')) ^
       *   bytes4(keccak256('enableBundling()'))
	   */
}

// File: contracts/BasicMultiToken.sol

contract BasicMultiToken is Ownable, StandardToken, DetailedERC20, ERC1003Token, IBasicMultiToken, SupportsInterfaceWithLookup {
    using CheckedERC20 for ERC20;
    using CheckedERC20 for DetailedERC20;

    ERC20[] private _tokens;
    uint private _inLendingMode;
    bool private _bundlingEnabled = true;

    event Bundle(address indexed who, address indexed beneficiary, uint256 value);
    event Unbundle(address indexed who, address indexed beneficiary, uint256 value);
    event BundlingStatus(bool enabled);

    modifier notInLendingMode {
        require(_inLendingMode == 0, "Operation can't be performed while lending");
        _;
    }

    modifier whenBundlingEnabled {
        require(_bundlingEnabled, "Bundling is disabled");
        _;
    }

    constructor()
        public DetailedERC20("", "", 0)
    {
    }

    function init(ERC20[] tokens, string theName, string theSymbol, uint8 theDecimals) public {
        require(decimals == 0, "constructor: decimals should be zero");
        require(theDecimals > 0, "constructor: _decimals should not be zero");
        require(bytes(theName).length > 0, "constructor: name should not be empty");
        require(bytes(theSymbol).length > 0, "constructor: symbol should not be empty");
        require(tokens.length >= 2, "Contract does not support less than 2 inner tokens");

        name = theName;
        symbol = theSymbol;
        decimals = theDecimals;
        _tokens = tokens;

        _registerInterface(InterfaceId_IBasicMultiToken);
    }

    function tokensCount() public view returns(uint) {
        return _tokens.length;
    }

    function tokens(uint i) public view returns(ERC20) {
        return _tokens[i];
    }

    function inLendingMode() public view returns(uint) {
        return _inLendingMode;
    }

    function bundlingEnabled() public view returns(bool) {
        return _bundlingEnabled;
    }

    function bundleFirstTokens(address beneficiary, uint256 amount, uint256[] tokenAmounts) public whenBundlingEnabled notInLendingMode {
        require(totalSupply_ == 0, "bundleFirstTokens: This method can be used with zero total supply only");
        _bundle(beneficiary, amount, tokenAmounts);
    }

    function bundle(address beneficiary, uint256 amount) public whenBundlingEnabled notInLendingMode {
        require(totalSupply_ != 0, "This method can be used with non zero total supply only");
        uint256[] memory tokenAmounts = new uint256[](_tokens.length);
        for (uint i = 0; i < _tokens.length; i++) {
            tokenAmounts[i] = _tokens[i].balanceOf(this).mul(amount).div(totalSupply_);
        }
        _bundle(beneficiary, amount, tokenAmounts);
    }

    function unbundle(address beneficiary, uint256 value) public notInLendingMode {
        unbundleSome(beneficiary, value, _tokens);
    }

    function unbundleSome(address beneficiary, uint256 value, ERC20[] someTokens) public notInLendingMode {
        _unbundle(beneficiary, value, someTokens);
    }

    // Admin methods

    function disableBundling() public onlyOwner {
        require(_bundlingEnabled, "Bundling is already disabled");
        _bundlingEnabled = false;
        emit BundlingStatus(false);
    }

    function enableBundling() public onlyOwner {
        require(!_bundlingEnabled, "Bundling is already enabled");
        _bundlingEnabled = true;
        emit BundlingStatus(true);
    }

    // Internal methods

    function _bundle(address beneficiary, uint256 amount, uint256[] tokenAmounts) internal {
        require(amount != 0, "Bundling amount should be non-zero");
        require(_tokens.length == tokenAmounts.length, "Lenghts of _tokens and tokenAmounts array should be equal");

        for (uint i = 0; i < _tokens.length; i++) {
            require(tokenAmounts[i] != 0, "Token amount should be non-zero");
            _tokens[i].checkedTransferFrom(msg.sender, this, tokenAmounts[i]);
        }

        totalSupply_ = totalSupply_.add(amount);
        balances[beneficiary] = balances[beneficiary].add(amount);
        emit Bundle(msg.sender, beneficiary, amount);
        emit Transfer(0, beneficiary, amount);
    }

    function _unbundle(address beneficiary, uint256 value, ERC20[] someTokens) internal {
        require(someTokens.length > 0, "Array of someTokens can't be empty");

        uint256 totalSupply = totalSupply_;
        balances[msg.sender] = balances[msg.sender].sub(value);
        totalSupply_ = totalSupply.sub(value);
        emit Unbundle(msg.sender, beneficiary, value);
        emit Transfer(msg.sender, 0, value);

        for (uint i = 0; i < someTokens.length; i++) {
            for (uint j = 0; j < i; j++) {
                require(someTokens[i] != someTokens[j], "unbundleSome: should not unbundle same token multiple times");
            }
            uint256 tokenAmount = someTokens[i].balanceOf(this).mul(value).div(totalSupply);
            someTokens[i].checkedTransfer(beneficiary, tokenAmount);
        }
    }

    // Instant Loans

    function lend(address to, ERC20 token, uint256 amount, address target, bytes data) public payable {
        uint256 prevBalance = token.balanceOf(this);
        token.asmTransfer(to, amount);
        _inLendingMode += 1;
        require(caller().makeCall.value(msg.value)(target, data), "lend: arbitrary call failed");
        _inLendingMode -= 1;
        require(token.balanceOf(this) >= prevBalance, "lend: lended token must be refilled");
    }
}

// File: contracts/FeeBasicMultiToken.sol

contract FeeBasicMultiToken is Ownable, BasicMultiToken {
    using CheckedERC20 for ERC20;

    uint256 constant public TOTAL_PERCRENTS = 1000000;
    uint256 internal _lendFee;

    function lendFee() public view returns(uint256) {
        return _lendFee;
    }

    function setLendFee(uint256 theLendFee) public onlyOwner {
        require(theLendFee <= 30000, "setLendFee: fee should be not greater than 3%");
        _lendFee = theLendFee;
    }

    function lend(address to, ERC20 token, uint256 amount, address target, bytes data) public payable {
        uint256 expectedBalance = token.balanceOf(this).mul(TOTAL_PERCRENTS.add(_lendFee)).div(TOTAL_PERCRENTS);
        super.lend(to, token, amount, target, data);
        require(token.balanceOf(this) >= expectedBalance, "lend: tokens must be returned with lend fee");
    }
}

// File: contracts/interface/IMultiToken.sol

contract IMultiToken is IBasicMultiToken {
    event Update();
    event Change(address indexed _fromToken, address indexed _toToken, address indexed _changer, uint256 _amount, uint256 _return);

    function weights(address _token) public view returns(uint256);
    function changesEnabled() public view returns(bool);
    
    function getReturn(address _fromToken, address _toToken, uint256 _amount) public view returns (uint256 returnAmount);
    function change(address _fromToken, address _toToken, uint256 _amount, uint256 _minReturn) public returns (uint256 returnAmount);

    // Owner methods
    function disableChanges() public;

    bytes4 public constant InterfaceId_IMultiToken = 0x81624e24;
	  /**
	   * 0x81624e24 ===
       *   InterfaceId_IBasicMultiToken(0xd5c368b6) ^
	   *   bytes4(keccak256('weights(address)')) ^
       *   bytes4(keccak256('changesEnabled()')) ^
       *   bytes4(keccak256('getReturn(address,address,uint256)')) ^
	   *   bytes4(keccak256('change(address,address,uint256,uint256)')) ^
       *   bytes4(keccak256('disableChanges()'))
	   */
}

// File: contracts/MultiToken.sol

contract MultiToken is IMultiToken, BasicMultiToken {
    using CheckedERC20 for ERC20;

    mapping(address => uint256) private _weights;
    uint256 internal _minimalWeight;
    bool private _changesEnabled = true;

    event ChangesDisabled();

    modifier whenChangesEnabled {
        require(_changesEnabled, "Operation can't be performed because changes are disabled");
        _;
    }

    function weights(address _token) public view returns(uint256) {
        return _weights[_token];
    }

    function changesEnabled() public view returns(bool) {
        return _changesEnabled;
    }

    function init(ERC20[] tokens, uint256[] tokenWeights, string theName, string theSymbol, uint8 theDecimals) public {
        super.init(tokens, theName, theSymbol, theDecimals);
        require(tokenWeights.length == tokens.length, "Lenghts of tokens and tokenWeights array should be equal");

        uint256 minimalWeight = 0;
        for (uint i = 0; i < tokens.length; i++) {
            require(tokenWeights[i] != 0, "The tokenWeights array should not contains zeros");
            require(_weights[tokens[i]] == 0, "The tokens array have duplicates");
            _weights[tokens[i]] = tokenWeights[i];
            if (minimalWeight == 0 || tokenWeights[i] < minimalWeight) {
                minimalWeight = tokenWeights[i];
            }
        }
        _minimalWeight = minimalWeight;

        _registerInterface(InterfaceId_IMultiToken);
    }

    function getReturn(address fromToken, address toToken, uint256 amount) public view returns(uint256 returnAmount) {
        if (_weights[fromToken] > 0 && _weights[toToken] > 0 && fromToken != toToken) {
            uint256 fromBalance = ERC20(fromToken).balanceOf(this);
            uint256 toBalance = ERC20(toToken).balanceOf(this);
            returnAmount = amount.mul(toBalance).mul(_weights[fromToken]).div(
                amount.mul(_weights[fromToken]).div(_minimalWeight).add(fromBalance).mul(_weights[toToken])
            );
        }
    }

    function change(address fromToken, address toToken, uint256 amount, uint256 minReturn) public whenChangesEnabled notInLendingMode returns(uint256 returnAmount) {
        returnAmount = getReturn(fromToken, toToken, amount);
        require(returnAmount > 0, "The return amount is zero");
        require(returnAmount >= minReturn, "The return amount is less than minReturn value");

        ERC20(fromToken).checkedTransferFrom(msg.sender, this, amount);
        ERC20(toToken).checkedTransfer(msg.sender, returnAmount);

        emit Change(fromToken, toToken, msg.sender, amount, returnAmount);
    }

    // Admin methods

    function disableChanges() public onlyOwner {
        require(_changesEnabled, "Changes are already disabled");
        _changesEnabled = false;
        emit ChangesDisabled();
    }

    // Internal methods

    function setWeight(address token, uint256 newWeight) internal {
        _weights[token] = newWeight;
    }
}

// File: contracts/FeeMultiToken.sol

contract FeeMultiToken is MultiToken, FeeBasicMultiToken {
    using CheckedERC20 for ERC20;

    uint256 internal _changeFee;
    uint256 internal _referralFee;

    function changeFee() public view returns(uint256) {
        return _changeFee;
    }

    function referralFee() public view returns(uint256) {
        return _referralFee;
    }

    function setChangeFee(uint256 theChangeFee) public onlyOwner {
        require(theChangeFee <= 30000, "setChangeFee: fee should be not greater than 3%");
        _changeFee = theChangeFee;
    }

    function setReferralFee(uint256 theReferralFee) public onlyOwner {
        require(theReferralFee <= 500000, "setReferralFee: fee should be not greater than 50% of changeFee");
        _referralFee = theReferralFee;
    }

    function getReturn(address fromToken, address toToken, uint256 amount) public view returns(uint256 returnAmount) {
        returnAmount = super.getReturn(fromToken, toToken, amount).mul(TOTAL_PERCRENTS.sub(_changeFee)).div(TOTAL_PERCRENTS);
    }

    function change(address fromToken, address toToken, uint256 amount, uint256 minReturn) public returns(uint256 returnAmount) {
        returnAmount = changeWithRef(fromToken, toToken, amount, minReturn, 0);
    }

    function changeWithRef(address fromToken, address toToken, uint256 amount, uint256 minReturn, address ref) public returns(uint256 returnAmount) {
        returnAmount = super.change(fromToken, toToken, amount, minReturn);
        uint256 refferalAmount = returnAmount
            .mul(_changeFee).div(TOTAL_PERCRENTS.sub(_changeFee))
            .mul(_referralFee).div(TOTAL_PERCRENTS);

        ERC20(toToken).checkedTransfer(ref, refferalAmount);
    }
}

// File: contracts/implementation/AstraMultiToken.sol

contract AstraMultiToken is FeeMultiToken {
    function init(ERC20[] tokens, uint256[] tokenWeights, string theName, string theSymbol, uint8 /*theDecimals*/) public {
        super.init(tokens, tokenWeights, theName, theSymbol, 18);
    }
}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[],"name":"changeFee","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","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":"fromToken","type":"address"},{"name":"toToken","type":"address"},{"name":"amount","type":"uint256"},{"name":"minReturn","type":"uint256"},{"name":"ref","type":"address"}],"name":"changeWithRef","outputs":[{"name":"returnAmount","type":"uint256"}],"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":"InterfaceId_ERC165","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"fromToken","type":"address"},{"name":"toToken","type":"address"},{"name":"amount","type":"uint256"}],"name":"getReturn","outputs":[{"name":"returnAmount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"inLendingMode","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"bundlingEnabled","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"beneficiary","type":"address"},{"name":"amount","type":"uint256"},{"name":"tokenAmounts","type":"uint256[]"}],"name":"bundleFirstTokens","outputs":[],"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":"disableBundling","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":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"}],"name":"transferAndCall","outputs":[{"name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"tokens","type":"address[]"},{"name":"theName","type":"string"},{"name":"theSymbol","type":"string"},{"name":"theDecimals","type":"uint8"}],"name":"init","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"lendFee","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"i","type":"uint256"}],"name":"tokens","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"fromToken","type":"address"},{"name":"toToken","type":"address"},{"name":"amount","type":"uint256"},{"name":"minReturn","type":"uint256"}],"name":"change","outputs":[{"name":"returnAmount","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_subtractedValue","type":"uint256"}],"name":"decreaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"tokens","type":"address[]"},{"name":"tokenWeights","type":"uint256[]"},{"name":"theName","type":"string"},{"name":"theSymbol","type":"string"},{"name":"","type":"uint8"}],"name":"init","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"theReferralFee","type":"uint256"}],"name":"setReferralFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"changesEnabled","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"referralFee","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokensCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_token","type":"address"}],"name":"weights","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","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":false,"inputs":[{"name":"beneficiary","type":"address"},{"name":"value","type":"uint256"}],"name":"unbundle","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"token","type":"address"},{"name":"amount","type":"uint256"},{"name":"target","type":"address"},{"name":"data","type":"bytes"}],"name":"lend","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"beneficiary","type":"address"},{"name":"value","type":"uint256"},{"name":"someTokens","type":"address[]"}],"name":"unbundleSome","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"theChangeFee","type":"uint256"}],"name":"setChangeFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"disableChanges","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"value","type":"uint256"},{"name":"data","type":"bytes"}],"name":"approveAndCall","outputs":[{"name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_addedValue","type":"uint256"}],"name":"increaseApproval","outputs":[{"name":"","type":"bool"}],"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":"theLendFee","type":"uint256"}],"name":"setLendFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"InterfaceId_IMultiToken","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"InterfaceId_IBasicMultiToken","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"beneficiary","type":"address"},{"name":"amount","type":"uint256"}],"name":"bundle","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"enableBundling","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":"TOTAL_PERCRENTS","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"caller","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"anonymous":false,"inputs":[],"name":"ChangesDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"who","type":"address"},{"indexed":true,"name":"beneficiary","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Bundle","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"who","type":"address"},{"indexed":true,"name":"beneficiary","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Unbundle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"enabled","type":"bool"}],"name":"BundlingStatus","type":"event"},{"anonymous":false,"inputs":[],"name":"Update","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_fromToken","type":"address"},{"indexed":true,"name":"_toToken","type":"address"},{"indexed":true,"name":"_changer","type":"address"},{"indexed":false,"name":"_amount","type":"uint256"},{"indexed":false,"name":"_return","type":"uint256"}],"name":"Change","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"}],"name":"OwnershipRenounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"}]

60806040526200000e62000186565b604051809103906000f0801580156200002b573d6000803e3d6000fd5b5060068054600160a060020a03929092166101000261010060a860020a0319909216919091179055600b805460ff199081166001908117909255600e80549091169091179055604080516020818101808452600080845284519283019094528382528354600160a060020a03191633178455825192939192620000b19160049162000197565b508151620000c790600590602085019062000197565b506006805460ff191660ff92909216919091179055506200011390507f01ffc9a70000000000000000000000000000000000000000000000000000000064010000000062000119810204565b6200023c565b7fffffffff0000000000000000000000000000000000000000000000000000000080821614156200014957600080fd5b7fffffffff00000000000000000000000000000000000000000000000000000000166000908152600860205260409020805460ff19166001179055565b6040516102bf8062003cf483390190565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620001da57805160ff19168380011785556200020a565b828001600101855582156200020a579182015b828111156200020a578251825591602001919060010190620001ed565b50620002189291506200021c565b5090565b6200023991905b8082111562000218576000815560010162000223565b90565b613aa8806200024c6000396000f3006080604052600436106102205763ffffffff60e060020a60003504166240ff6c811461022557806301ffc9a71461024c57806306fdde0314610282578063095ea7b31461030c578063179743991461033057806318160ddd1461036557806319fa8f501461037a5780631e1401f8146103ac5780631f400477146103d657806321f38c6e146103eb57806322393ef41461040057806323b872dd1461046957806330e26cb814610493578063313ce567146104a85780634000aea0146104d35780634686b4be1461052f5780634aea0aec146106055780634f64b2be1461061a5780635e5144eb1461064e578063661884631461067b5780636f5f535d1461069f57806370a08231146107ae578063713494d7146107cf578063715018a6146107e757806376cc5fdf146107fc57806384ae2bc6146108115780638da5cb5b1461082657806395d89b411461083b578063a64ed8ba14610850578063a7cac84614610865578063a9059cbb14610886578063b4dc3dc7146108aa578063be5afb1a146108ce578063be7e18ed14610939578063c108adab146109a0578063c5e2f418146109b8578063cae9ca51146109cd578063d73dd62314610a29578063dd62ed3e14610a4d578063df1614cf14610a74578063e82b900014610a8c578063e8f88eaa14610aa1578063eba3cdfe14610ab6578063eec0344414610ada578063f2fde38b14610aef578063f9f7d9de14610b10578063fc9c8d3914610b25575b600080fd5b34801561023157600080fd5b5061023a610b3a565b60408051918252519081900360200190f35b34801561025857600080fd5b5061026e600160e060020a031960043516610b41565b604080519115158252519081900360200190f35b34801561028e57600080fd5b50610297610b60565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102d15781810151838201526020016102b9565b50505050905090810190601f1680156102fe5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561031857600080fd5b5061026e600160a060020a0360043516602435610bee565b34801561033c57600080fd5b5061023a600160a060020a03600435811690602435811690604435906064359060843516610c55565b34801561037157600080fd5b5061023a610ce0565b34801561038657600080fd5b5061038f610ce6565b60408051600160e060020a03199092168252519081900360200190f35b3480156103b857600080fd5b5061023a600160a060020a0360043581169060243516604435610d0a565b3480156103e257600080fd5b5061023a610d41565b3480156103f757600080fd5b5061026e610d47565b34801561040c57600080fd5b506040805160206004604435818101358381028086018501909652808552610467958335600160a060020a0316956024803596369695606495939492019291829185019084908082843750949750610d509650505050505050565b005b34801561047557600080fd5b5061026e600160a060020a0360043581169060243516604435610eba565b34801561049f57600080fd5b50610467610f1e565b3480156104b457600080fd5b506104bd610fd1565b6040805160ff9092168252519081900360200190f35b604080516020600460443581810135601f810184900484028501840190955284845261026e948235600160a060020a0316946024803595369594606494920191908190840183828082843750949750610fda9650505050505050565b34801561053b57600080fd5b50604080516020600480358082013583810280860185019096528085526104679536959394602494938501929182918501908490808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a9998810197919650918201945092508291508401838280828437509497505050923560ff16935061110192505050565b34801561061157600080fd5b5061023a6113fa565b34801561062657600080fd5b50610632600435611400565b60408051600160a060020a039092168252519081900360200190f35b34801561065a57600080fd5b5061023a600160a060020a036004358116906024351660443560643561142c565b34801561068757600080fd5b5061026e600160a060020a036004351660243561143c565b3480156106ab57600080fd5b506040805160206004803580820135838102808601850190965280855261046795369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a99890198929750908201955093508392508501908490808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a9998810197919650918201945092508291508401838280828437509497505050923560ff16935061152b92505050565b3480156107ba57600080fd5b5061023a600160a060020a0360043516611540565b3480156107db57600080fd5b5061046760043561155b565b3480156107f357600080fd5b506104676115f8565b34801561080857600080fd5b5061026e611664565b34801561081d57600080fd5b5061023a61166d565b34801561083257600080fd5b50610632611673565b34801561084757600080fd5b50610297611682565b34801561085c57600080fd5b5061023a6116dd565b34801561087157600080fd5b5061023a600160a060020a03600435166116e3565b34801561089257600080fd5b5061026e600160a060020a03600435166024356116fe565b3480156108b657600080fd5b50610467600160a060020a03600435166024356117cd565b604080516020600460843581810135601f8101849004840285018401909552848452610467948235600160a060020a0390811695602480358316966044359660643590941695369560a494939091019181908401838280828437509497506118909650505050505050565b34801561094557600080fd5b506040805160206004604435818101358381028086018501909652808552610467958335600160a060020a0316956024803596369695606495939492019291829185019084908082843750949750611a449650505050505050565b3480156109ac57600080fd5b50610467600435611aa9565b3480156109c457600080fd5b50610467611b45565b604080516020600460443581810135601f810184900484028501840190955284845261026e948235600160a060020a0316946024803595369594606494920191908190840183828082843750949750611bed9650505050505050565b348015610a3557600080fd5b5061026e600160a060020a0360043516602435611d74565b348015610a5957600080fd5b5061023a600160a060020a0360043581169060243516611e0d565b348015610a8057600080fd5b50610467600435611e38565b348015610a9857600080fd5b5061038f611ed4565b348015610aad57600080fd5b5061038f611ef8565b348015610ac257600080fd5b50610467600160a060020a0360043516602435611f1c565b348015610ae657600080fd5b50610467612133565b348015610afb57600080fd5b50610467600160a060020a03600435166121e9565b348015610b1c57600080fd5b5061023a61220c565b348015610b3157600080fd5b50610632612213565b6010545b90565b600160e060020a03191660009081526008602052604090205460ff1690565b6004805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610be65780601f10610bbb57610100808354040283529160200191610be6565b820191906000526020600020905b815481529060010190602001808311610bc957829003601f168201915b505050505081565b336000818152600360209081526040808320600160a060020a038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a35060015b92915050565b600080610c6487878787612227565b9150610cba620f4240610ca2601154610cae610c8e601054620f424061248390919063ffffffff16565b601054610ca290899063ffffffff61249516565b9063ffffffff6124be16565b9063ffffffff61249516565b9050610cd6600160a060020a038716848363ffffffff6124d316565b5095945050505050565b60025490565b7f01ffc9a70000000000000000000000000000000000000000000000000000000081565b6000610d39620f4240610ca2610d2e601054620f424061248390919063ffffffff16565b610cae888888612664565b949350505050565b600a5490565b600b5460ff1690565b600b5460ff161515610dac576040805160e560020a62461bcd02815260206004820152601460248201527f42756e646c696e672069732064697361626c6564000000000000000000000000604482015290519081900360640190fd5b600a5415610e06576040805160e560020a62461bcd02815260206004820152602a6024820152600080516020613a3d8339815191526044820152600080516020613a1d833981519152606482015290519081900360840190fd5b60025415610eaa576040805160e560020a62461bcd02815260206004820152604660248201527f62756e646c654669727374546f6b656e733a2054686973206d6574686f64206360448201527f616e20626520757365642077697468207a65726f20746f74616c20737570706c60648201527f79206f6e6c790000000000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b610eb583838361284b565b505050565b6006546000908190600160a060020a03868116610100909204161415610f0657600780546000198101908110610eec57fe5b600091825260209091200154600160a060020a0316610f08565b845b9050610f15818585612ae6565b95945050505050565b600054600160a060020a03163314610f3557600080fd5b600b5460ff161515610f91576040805160e560020a62461bcd02815260206004820152601c60248201527f42756e646c696e6720697320616c72656164792064697361626c656400000000604482015290519081900360640190fd5b600b805460ff19169055604080516000815290517fcd495a5e98995df10f680f215ceaac5420ab5f1e24457a3fcdf19a91ad1079f19181900360200190a1565b60065460ff1681565b6000610fe684846116fe565b50600654604080517f1cb9ce63000000000000000000000000000000000000000000000000000000008152600160a060020a03878116600483019081526024830193845286516044840152865161010090950490911693631cb9ce639334938a93899390929160640190602085019080838360005b8381101561107357818101518382015260200161105b565b50505050905090810190601f1680156110a05780820380516001836020036101000a031916815260200191505b5093505050506020604051808303818588803b1580156110bf57600080fd5b505af11580156110d3573d6000803e3d6000fd5b50505050506040513d60208110156110ea57600080fd5b505115156110f757600080fd5b5060019392505050565b60065460ff1615611181576040805160e560020a62461bcd028152602060048201526024808201527f636f6e7374727563746f723a20646563696d616c732073686f756c642062652060448201527f7a65726f00000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600060ff821611611202576040805160e560020a62461bcd02815260206004820152602960248201527f636f6e7374727563746f723a205f646563696d616c732073686f756c64206e6f60448201527f74206265207a65726f0000000000000000000000000000000000000000000000606482015290519081900360840190fd5b8251600010611281576040805160e560020a62461bcd02815260206004820152602560248201527f636f6e7374727563746f723a206e616d652073686f756c64206e6f742062652060448201527f656d707479000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b8151600010611300576040805160e560020a62461bcd02815260206004820152602760248201527f636f6e7374727563746f723a2073796d626f6c2073686f756c64206e6f74206260448201527f6520656d70747900000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b835160021115611380576040805160e560020a62461bcd02815260206004820152603260248201527f436f6e747261637420646f6573206e6f7420737570706f7274206c657373207460448201527f68616e203220696e6e657220746f6b656e730000000000000000000000000000606482015290519081900360840190fd5b82516113939060049060208601906138c9565b5081516113a79060059060208501906138c9565b506006805460ff191660ff831617905583516113ca906009906020870190613943565b506113f47fd5c368b600000000000000000000000000000000000000000000000000000000612c4b565b50505050565b600f5490565b600060098281548110151561141157fe5b600091825260209091200154600160a060020a031692915050565b6000610f15858585856000610c55565b336000908152600360209081526040808320600160a060020a038616845290915281205480831061149057336000908152600360209081526040808320600160a060020a03881684529091528120556114c5565b6114a0818463ffffffff61248316565b336000908152600360209081526040808320600160a060020a03891684529091529020555b336000818152600360209081526040808320600160a060020a0389168085529083529281902054815190815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060019392505050565b611539858585856012612c87565b5050505050565b600160a060020a031660009081526001602052604090205490565b600054600160a060020a0316331461157257600080fd5b6207a1208111156115f3576040805160e560020a62461bcd02815260206004820152603f60248201527f736574526566657272616c4665653a206665652073686f756c64206265206e6f60448201527f742067726561746572207468616e20353025206f66206368616e676546656500606482015290519081900360840190fd5b601155565b600054600160a060020a0316331461160f57600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b600e5460ff1690565b60115490565b600054600160a060020a031681565b6005805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610be65780601f10610bbb57610100808354040283529160200191610be6565b60095490565b600160a060020a03166000908152600c602052604090205490565b3360009081526001602052604081205482111561171a57600080fd5b600160a060020a038316151561172f57600080fd5b3360009081526001602052604090205461174f908363ffffffff61248316565b3360009081526001602052604080822092909255600160a060020a03851681522054611781908363ffffffff612f1216565b600160a060020a038416600081815260016020908152604091829020939093558051858152905191923392600080516020613a5d8339815191529281900390910190a350600192915050565b600a5415611827576040805160e560020a62461bcd02815260206004820152602a6024820152600080516020613a3d8339815191526044820152600080516020613a1d833981519152606482015290519081900360840190fd5b61188c8282600980548060200260200160405190810160405280929190818152602001828054801561188257602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311611864575b5050505050611a44565b5050565b6000611937620f4240610ca26118b4600f54620f4240612f1290919063ffffffff16565b6040805160e060020a6370a082310281523060048201529051600160a060020a038b16916370a082319160248083019260209291908290030181600087803b1580156118ff57600080fd5b505af1158015611913573d6000803e3d6000fd5b505050506040513d602081101561192957600080fd5b50519063ffffffff61249516565b90506119468686868686612f1f565b6040805160e060020a6370a0823102815230600482015290518291600160a060020a038816916370a08231916024808201926020929091908290030181600087803b15801561199457600080fd5b505af11580156119a8573d6000803e3d6000fd5b505050506040513d60208110156119be57600080fd5b50511015611a3c576040805160e560020a62461bcd02815260206004820152602b60248201527f6c656e643a20746f6b656e73206d7573742062652072657475726e656420776960448201527f7468206c656e6420666565000000000000000000000000000000000000000000606482015290519081900360840190fd5b505050505050565b600a5415611a9e576040805160e560020a62461bcd02815260206004820152602a6024820152600080516020613a3d8339815191526044820152600080516020613a1d833981519152606482015290519081900360840190fd5b610eb583838361320e565b600054600160a060020a03163314611ac057600080fd5b617530811115611b40576040805160e560020a62461bcd02815260206004820152602f60248201527f7365744368616e67654665653a206665652073686f756c64206265206e6f742060448201527f67726561746572207468616e2033250000000000000000000000000000000000606482015290519081900360840190fd5b601055565b600054600160a060020a03163314611b5c57600080fd5b600e5460ff161515611bb8576040805160e560020a62461bcd02815260206004820152601c60248201527f4368616e6765732061726520616c72656164792064697361626c656400000000604482015290519081900360640190fd5b600e805460ff191690556040517f5fe2f33cb1aaeac88078a7189134f6b75107e50ba04e8324db46c533d760519890600090a1565b6007805460018101825560009182527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68801805473ffffffffffffffffffffffffffffffffffffffff191633179055611c458484610bee565b50600654604080517f1cb9ce63000000000000000000000000000000000000000000000000000000008152600160a060020a03878116600483019081526024830193845286516044840152865161010090950490911693631cb9ce639334938a93899390929160640190602085019080838360005b83811015611cd2578181015183820152602001611cba565b50505050905090810190601f168015611cff5780820380516001836020036101000a031916815260200191505b5093505050506020604051808303818588803b158015611d1e57600080fd5b505af1158015611d32573d6000803e3d6000fd5b50505050506040513d6020811015611d4957600080fd5b50511515611d5657600080fd5b600780546000190190611d6990826139b1565b506001949350505050565b336000908152600360209081526040808320600160a060020a0386168452909152812054611da8908363ffffffff612f1216565b336000818152600360209081526040808320600160a060020a0389168085529083529281902085905580519485525191937f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929081900390910190a350600192915050565b600160a060020a03918216600090815260036020908152604080832093909416825291909152205490565b600054600160a060020a03163314611e4f57600080fd5b617530811115611ecf576040805160e560020a62461bcd02815260206004820152602d60248201527f7365744c656e644665653a206665652073686f756c64206265206e6f7420677260448201527f6561746572207468616e20332500000000000000000000000000000000000000606482015290519081900360840190fd5b600f55565b7f81624e240000000000000000000000000000000000000000000000000000000081565b7fd5c368b60000000000000000000000000000000000000000000000000000000081565b600b5460609060009060ff161515611f7e576040805160e560020a62461bcd02815260206004820152601460248201527f42756e646c696e672069732064697361626c6564000000000000000000000000604482015290519081900360640190fd5b600a5415611fd8576040805160e560020a62461bcd02815260206004820152602a6024820152600080516020613a3d8339815191526044820152600080516020613a1d833981519152606482015290519081900360840190fd5b6002541515612057576040805160e560020a62461bcd02815260206004820152603760248201527f54686973206d6574686f642063616e20626520757365642077697468206e6f6e60448201527f207a65726f20746f74616c20737570706c79206f6e6c79000000000000000000606482015290519081900360840190fd5b600954604080518281526020808402820101909152908015612083578160200160208202803883390190505b509150600090505b60095481101561212857612108600254610ca2856009858154811015156120ae57fe5b60009182526020808320909101546040805160e060020a6370a082310281523060048201529051600160a060020a03909216936370a082319360248084019491939192918390030190829087803b1580156118ff57600080fd5b828281518110151561211657fe5b6020908102909101015260010161208b565b6113f484848461284b565b600054600160a060020a0316331461214a57600080fd5b600b5460ff16156121a5576040805160e560020a62461bcd02815260206004820152601b60248201527f42756e646c696e6720697320616c726561647920656e61626c65640000000000604482015290519081900360640190fd5b600b805460ff1916600190811790915560408051918252517fcd495a5e98995df10f680f215ceaac5420ab5f1e24457a3fcdf19a91ad1079f19181900360200190a1565b600054600160a060020a0316331461220057600080fd5b612209816134d0565b50565b620f424081565b6006546101009004600160a060020a031690565b600e5460009060ff1615156122ac576040805160e560020a62461bcd02815260206004820152603960248201527f4f7065726174696f6e2063616e277420626520706572666f726d65642062656360448201527f61757365206368616e676573206172652064697361626c656400000000000000606482015290519081900360840190fd5b600a5415612306576040805160e560020a62461bcd02815260206004820152602a6024820152600080516020613a3d8339815191526044820152600080516020613a1d833981519152606482015290519081900360840190fd5b612311858585610d0a565b90506000811161236b576040805160e560020a62461bcd02815260206004820152601960248201527f5468652072657475726e20616d6f756e74206973207a65726f00000000000000604482015290519081900360640190fd5b818110156123e9576040805160e560020a62461bcd02815260206004820152602e60248201527f5468652072657475726e20616d6f756e74206973206c657373207468616e206d60448201527f696e52657475726e2076616c7565000000000000000000000000000000000000606482015290519081900360840190fd5b612404600160a060020a03861633308663ffffffff61354d16565b61241e600160a060020a038516338363ffffffff6124d316565b33600160a060020a031684600160a060020a031686600160a060020a03167f24cee3d6b5651a987362aa6216b9d34a39212f0f1967dfd48c2c3a4fc3c576dc8685604051808381526020018281526020019250505060405180910390a4949350505050565b60008282111561248f57fe5b50900390565b60008215156124a657506000610c4f565b508181028183828115156124b657fe5b0414610c4f57fe5b600081838115156124cb57fe5b049392505050565b6000808211156113f4576040805160e060020a6370a082310281523060048201529051600160a060020a038616916370a082319160248083019260209291908290030181600087803b15801561252857600080fd5b505af115801561253c573d6000803e3d6000fd5b505050506040513d602081101561255257600080fd5b505190506125618484846136ff565b50612572818363ffffffff61248316565b6040805160e060020a6370a082310281523060048201529051600160a060020a038716916370a082319160248083019260209291908290030181600087803b1580156125bd57600080fd5b505af11580156125d1573d6000803e3d6000fd5b505050506040513d60208110156125e757600080fd5b5051146113f4576040805160e560020a62461bcd02815260206004820152602b60248201527f636865636b65645472616e736665723a2046696e616c2062616c616e6365206460448201527f69646e2774206d61746368000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a0383166000908152600c602052604081205481908190811080156126a55750600160a060020a0385166000908152600c6020526040812054115b80156126c3575084600160a060020a031686600160a060020a031614155b15612842576040805160e060020a6370a082310281523060048201529051600160a060020a038816916370a082319160248083019260209291908290030181600087803b15801561271357600080fd5b505af1158015612727573d6000803e3d6000fd5b505050506040513d602081101561273d57600080fd5b50516040805160e060020a6370a082310281523060048201529051919350600160a060020a038716916370a08231916024808201926020929091908290030181600087803b15801561278e57600080fd5b505af11580156127a2573d6000803e3d6000fd5b505050506040513d60208110156127b857600080fd5b5051600160a060020a038087166000908152600c602052604080822054600d54938b16835291205492935061283f9261281292610cae91879161280691610ca2908c9063ffffffff61249516565b9063ffffffff612f1216565b600160a060020a0388166000908152600c6020526040902054610ca290610cae888663ffffffff61249516565b92505b50509392505050565b60008215156128ca576040805160e560020a62461bcd02815260206004820152602260248201527f42756e646c696e6720616d6f756e742073686f756c64206265206e6f6e2d7a6560448201527f726f000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b81516009541461294a576040805160e560020a62461bcd02815260206004820152603960248201527f4c656e67687473206f66205f746f6b656e7320616e6420746f6b656e416d6f7560448201527f6e74732061727261792073686f756c6420626520657175616c00000000000000606482015290519081900360840190fd5b5060005b600954811015612a1d57818181518110151561296657fe5b6020908102909101015115156129c6576040805160e560020a62461bcd02815260206004820152601f60248201527f546f6b656e20616d6f756e742073686f756c64206265206e6f6e2d7a65726f00604482015290519081900360640190fd5b612a15333084848151811015156129d957fe5b906020019060200201516009858154811015156129f257fe5b600091825260209091200154600160a060020a031692919063ffffffff61354d16565b60010161294e565b600254612a30908463ffffffff612f1216565b600255600160a060020a038416600090815260016020526040902054612a5c908463ffffffff612f1216565b600160a060020a0385166000818152600160209081526040918290209390935580518681529051919233927f6401d28c11d9f5749b7d2848c2af727680ae93ed2c51ac22e65ed498fb8dcb419281900390910190a3604080518481529051600160a060020a03861691600091600080516020613a5d8339815191529181900360200190a350505050565b600160a060020a038316600090815260016020526040812054821115612b0b57600080fd5b600160a060020a0384166000908152600360209081526040808320338452909152902054821115612b3b57600080fd5b600160a060020a0383161515612b5057600080fd5b600160a060020a038416600090815260016020526040902054612b79908363ffffffff61248316565b600160a060020a038086166000908152600160205260408082209390935590851681522054612bae908363ffffffff612f1216565b600160a060020a038085166000908152600160209081526040808320949094559187168152600382528281203382529091522054612bf2908363ffffffff61248316565b600160a060020a0380861660008181526003602090815260408083203384528252918290209490945580518681529051928716939192600080516020613a5d833981519152929181900390910190a35060019392505050565b600160e060020a03198082161415612c6257600080fd5b600160e060020a0319166000908152600860205260409020805460ff19166001179055565b600080612c9687868686611101565b8651865114612d15576040805160e560020a62461bcd02815260206004820152603860248201527f4c656e67687473206f6620746f6b656e7320616e6420746f6b656e576569676860448201527f74732061727261792073686f756c6420626520657175616c0000000000000000606482015290519081900360840190fd5b5060009050805b8651811015612edb578581815181101515612d3357fe5b602090810290910101511515612db9576040805160e560020a62461bcd02815260206004820152603060248201527f54686520746f6b656e576569676874732061727261792073686f756c64206e6f60448201527f7420636f6e7461696e73207a65726f7300000000000000000000000000000000606482015290519081900360840190fd5b600c60008883815181101515612dcb57fe5b6020908102909101810151600160a060020a031682528101919091526040016000205415612e43576040805160e560020a62461bcd02815260206004820181905260248201527f54686520746f6b656e732061727261792068617665206475706c696361746573604482015290519081900360640190fd5b8581815181101515612e5157fe5b90602001906020020151600c60008984815181101515612e6d57fe5b6020908102909101810151600160a060020a0316825281019190915260400160002055811580612eb35750818682815181101515612ea757fe5b90602001906020020151105b15612ed3578581815181101515612ec657fe5b9060200190602002015191505b600101612d1c565b600d829055612f097f81624e2400000000000000000000000000000000000000000000000000000000612c4b565b50505050505050565b81810182811015610c4f57fe5b6040805160e060020a6370a082310281523060048201529051600091600160a060020a038716916370a082319160248082019260209290919082900301818787803b158015612f6d57600080fd5b505af1158015612f81573d6000803e3d6000fd5b505050506040513d6020811015612f9757600080fd5b50519050612fb5600160a060020a038616878663ffffffff6136ff16565b50600a80546001019055612fc7612213565b600160a060020a0316631cb9ce633485856040518463ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561303f578181015183820152602001613027565b50505050905090810190601f16801561306c5780820380516001836020036101000a031916815260200191505b5093505050506020604051808303818588803b15801561308b57600080fd5b505af115801561309f573d6000803e3d6000fd5b50505050506040513d60208110156130b657600080fd5b5051151561310e576040805160e560020a62461bcd02815260206004820152601b60248201527f6c656e643a206172626974726172792063616c6c206661696c65640000000000604482015290519081900360640190fd5b600a80546000190190556040805160e060020a6370a0823102815230600482015290518291600160a060020a038816916370a08231916024808201926020929091908290030181600087803b15801561316657600080fd5b505af115801561317a573d6000803e3d6000fd5b505050506040513d602081101561319057600080fd5b50511015611a3c576040805160e560020a62461bcd02815260206004820152602360248201527f6c656e643a206c656e64656420746f6b656e206d75737420626520726566696c60448201527f6c65640000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60008060008060008551111515613295576040805160e560020a62461bcd02815260206004820152602260248201527f4172726179206f6620736f6d65546f6b656e732063616e277420626520656d7060448201527f7479000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600254336000908152600160205260409020549094506132bb908763ffffffff61248316565b336000908152600160205260409020556132db848763ffffffff61248316565b600255604080518781529051600160a060020a0389169133917f8c85614f24f81c7b85c9837ab8277cfc5062dea12393fe90c757220926b07a7b9181900360200190a36040805187815290516000913391600080516020613a5d8339815191529181900360200190a3600092505b8451831015612f0957600091505b8282101561342857848281518110151561336d57fe5b90602001906020020151600160a060020a0316858481518110151561338e57fe5b60209081029091010151600160a060020a0316141561341d576040805160e560020a62461bcd02815260206004820152603b60248201527f756e62756e646c65536f6d653a2073686f756c64206e6f7420756e62756e646c60448201527f652073616d6520746f6b656e206d756c7469706c652074696d65730000000000606482015290519081900360840190fd5b600190910190613357565b61349084610ca288888781518110151561343e57fe5b60209081029091018101516040805160e060020a6370a082310281523060048201529051600160a060020a03909216926370a08231926024808401938290030181600087803b1580156118ff57600080fd5b90506134c5878287868151811015156134a557fe5b60209081029091010151600160a060020a0316919063ffffffff6124d316565b600190920191613349565b600160a060020a03811615156134e557600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b6000808211156115395784600160a060020a03166370a08231846040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b1580156135b257600080fd5b505af11580156135c6573d6000803e3d6000fd5b505050506040513d60208110156135dc57600080fd5b505190506135ec858585856137bb565b506135fd818363ffffffff612f1216565b85600160a060020a03166370a08231856040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b15801561365857600080fd5b505af115801561366c573d6000803e3d6000fd5b505050506040513d602081101561368257600080fd5b505114611539576040805160e560020a62461bcd02815260206004820152602b60248201527f636865636b65645472616e736665723a2046696e616c2062616c616e6365206460448201527f69646e2774206d61746368000000000000000000000000000000000000000000606482015290519081900360840190fd5b600061370a84613892565b151561371557600080fd5b83600160a060020a031660405180807f7472616e7366657228616464726573732c75696e7432353629000000000000008152506019019050604051809103902060e060020a900484846040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a03168152602001828152602001925050506000604051808303816000875af19250505015156137b357600080fd5b610d3961389a565b60006137c685613892565b15156137d157600080fd5b604080517f7472616e7366657246726f6d28616464726573732c616464726573732c75696e81527f74323536290000000000000000000000000000000000000000000000000000006020820152815190819003602501812063ffffffff60e060020a918290049081169091028252600160a060020a0387811660048401528681166024840152604483018690529251928816929091606480820192600092909190829003018183875af192505050151561388a57600080fd5b610f1561389a565b6000903b1190565b60003d80156138b057602081146138b957600080fd5b600191506138c5565b60206000803e60005191505b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061390a57805160ff1916838001178555613937565b82800160010185558215613937579182015b8281111561393757825182559160200191906001019061391c565b506138c59291506139d1565b8280548282559060005260206000209081019282156139a5579160200282015b828111156139a5578251825473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03909116178255602090920191600190910190613963565b506138c59291506139eb565b815481835581811115610eb557600083815260209020610eb59181019083015b610b3e91905b808211156138c557600081556001016139d7565b610b3e91905b808211156138c557805473ffffffffffffffffffffffffffffffffffffffff191681556001016139f156006c65206c656e64696e67000000000000000000000000000000000000000000004f7065726174696f6e2063616e277420626520706572666f726d656420776869ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa165627a7a723058208f9721030d60da9e6d1e14a3bd46bae277e5c793dbdd1f450c16d1073a64b5b00029608060405260008054600160a060020a0319163317905561029a806100256000396000f3006080604052600436106100615763ffffffff7c01000000000000000000000000000000000000000000000000000000006000350416631cb9ce638114610066578063715018a61461009a5780638da5cb5b146100b1578063f2fde38b146100e2575b600080fd5b61008660048035600160a060020a03169060248035908101910135610103565b604080519115158252519081900360200190f35b3480156100a657600080fd5b506100af610153565b005b3480156100bd57600080fd5b506100c66101bf565b60408051600160a060020a039092168252519081900360200190f35b3480156100ee57600080fd5b506100af600160a060020a03600435166101ce565b60008054600160a060020a0316331461011b57600080fd5b83600160a060020a03163484846040518083838082843782019150509250505060006040518083038185875af1979650505050505050565b600054600160a060020a0316331461016a57600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b600054600160a060020a031681565b600054600160a060020a031633146101e557600080fd5b6101ee816101f1565b50565b600160a060020a038116151561020657600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03929092169190911790555600a165627a7a723058207a6b008e1f74a0c8c8e140958295083644f33ccdf7d90f91fc1f4d58411ad7610029

Deployed Bytecode

0x6080604052600436106102205763ffffffff60e060020a60003504166240ff6c811461022557806301ffc9a71461024c57806306fdde0314610282578063095ea7b31461030c578063179743991461033057806318160ddd1461036557806319fa8f501461037a5780631e1401f8146103ac5780631f400477146103d657806321f38c6e146103eb57806322393ef41461040057806323b872dd1461046957806330e26cb814610493578063313ce567146104a85780634000aea0146104d35780634686b4be1461052f5780634aea0aec146106055780634f64b2be1461061a5780635e5144eb1461064e578063661884631461067b5780636f5f535d1461069f57806370a08231146107ae578063713494d7146107cf578063715018a6146107e757806376cc5fdf146107fc57806384ae2bc6146108115780638da5cb5b1461082657806395d89b411461083b578063a64ed8ba14610850578063a7cac84614610865578063a9059cbb14610886578063b4dc3dc7146108aa578063be5afb1a146108ce578063be7e18ed14610939578063c108adab146109a0578063c5e2f418146109b8578063cae9ca51146109cd578063d73dd62314610a29578063dd62ed3e14610a4d578063df1614cf14610a74578063e82b900014610a8c578063e8f88eaa14610aa1578063eba3cdfe14610ab6578063eec0344414610ada578063f2fde38b14610aef578063f9f7d9de14610b10578063fc9c8d3914610b25575b600080fd5b34801561023157600080fd5b5061023a610b3a565b60408051918252519081900360200190f35b34801561025857600080fd5b5061026e600160e060020a031960043516610b41565b604080519115158252519081900360200190f35b34801561028e57600080fd5b50610297610b60565b6040805160208082528351818301528351919283929083019185019080838360005b838110156102d15781810151838201526020016102b9565b50505050905090810190601f1680156102fe5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561031857600080fd5b5061026e600160a060020a0360043516602435610bee565b34801561033c57600080fd5b5061023a600160a060020a03600435811690602435811690604435906064359060843516610c55565b34801561037157600080fd5b5061023a610ce0565b34801561038657600080fd5b5061038f610ce6565b60408051600160e060020a03199092168252519081900360200190f35b3480156103b857600080fd5b5061023a600160a060020a0360043581169060243516604435610d0a565b3480156103e257600080fd5b5061023a610d41565b3480156103f757600080fd5b5061026e610d47565b34801561040c57600080fd5b506040805160206004604435818101358381028086018501909652808552610467958335600160a060020a0316956024803596369695606495939492019291829185019084908082843750949750610d509650505050505050565b005b34801561047557600080fd5b5061026e600160a060020a0360043581169060243516604435610eba565b34801561049f57600080fd5b50610467610f1e565b3480156104b457600080fd5b506104bd610fd1565b6040805160ff9092168252519081900360200190f35b604080516020600460443581810135601f810184900484028501840190955284845261026e948235600160a060020a0316946024803595369594606494920191908190840183828082843750949750610fda9650505050505050565b34801561053b57600080fd5b50604080516020600480358082013583810280860185019096528085526104679536959394602494938501929182918501908490808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a9998810197919650918201945092508291508401838280828437509497505050923560ff16935061110192505050565b34801561061157600080fd5b5061023a6113fa565b34801561062657600080fd5b50610632600435611400565b60408051600160a060020a039092168252519081900360200190f35b34801561065a57600080fd5b5061023a600160a060020a036004358116906024351660443560643561142c565b34801561068757600080fd5b5061026e600160a060020a036004351660243561143c565b3480156106ab57600080fd5b506040805160206004803580820135838102808601850190965280855261046795369593946024949385019291829185019084908082843750506040805187358901803560208181028481018201909552818452989b9a99890198929750908201955093508392508501908490808284375050604080516020601f89358b018035918201839004830284018301909452808352979a99988101979196509182019450925082915084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a9998810197919650918201945092508291508401838280828437509497505050923560ff16935061152b92505050565b3480156107ba57600080fd5b5061023a600160a060020a0360043516611540565b3480156107db57600080fd5b5061046760043561155b565b3480156107f357600080fd5b506104676115f8565b34801561080857600080fd5b5061026e611664565b34801561081d57600080fd5b5061023a61166d565b34801561083257600080fd5b50610632611673565b34801561084757600080fd5b50610297611682565b34801561085c57600080fd5b5061023a6116dd565b34801561087157600080fd5b5061023a600160a060020a03600435166116e3565b34801561089257600080fd5b5061026e600160a060020a03600435166024356116fe565b3480156108b657600080fd5b50610467600160a060020a03600435166024356117cd565b604080516020600460843581810135601f8101849004840285018401909552848452610467948235600160a060020a0390811695602480358316966044359660643590941695369560a494939091019181908401838280828437509497506118909650505050505050565b34801561094557600080fd5b506040805160206004604435818101358381028086018501909652808552610467958335600160a060020a0316956024803596369695606495939492019291829185019084908082843750949750611a449650505050505050565b3480156109ac57600080fd5b50610467600435611aa9565b3480156109c457600080fd5b50610467611b45565b604080516020600460443581810135601f810184900484028501840190955284845261026e948235600160a060020a0316946024803595369594606494920191908190840183828082843750949750611bed9650505050505050565b348015610a3557600080fd5b5061026e600160a060020a0360043516602435611d74565b348015610a5957600080fd5b5061023a600160a060020a0360043581169060243516611e0d565b348015610a8057600080fd5b50610467600435611e38565b348015610a9857600080fd5b5061038f611ed4565b348015610aad57600080fd5b5061038f611ef8565b348015610ac257600080fd5b50610467600160a060020a0360043516602435611f1c565b348015610ae657600080fd5b50610467612133565b348015610afb57600080fd5b50610467600160a060020a03600435166121e9565b348015610b1c57600080fd5b5061023a61220c565b348015610b3157600080fd5b50610632612213565b6010545b90565b600160e060020a03191660009081526008602052604090205460ff1690565b6004805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610be65780601f10610bbb57610100808354040283529160200191610be6565b820191906000526020600020905b815481529060010190602001808311610bc957829003601f168201915b505050505081565b336000818152600360209081526040808320600160a060020a038716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a35060015b92915050565b600080610c6487878787612227565b9150610cba620f4240610ca2601154610cae610c8e601054620f424061248390919063ffffffff16565b601054610ca290899063ffffffff61249516565b9063ffffffff6124be16565b9063ffffffff61249516565b9050610cd6600160a060020a038716848363ffffffff6124d316565b5095945050505050565b60025490565b7f01ffc9a70000000000000000000000000000000000000000000000000000000081565b6000610d39620f4240610ca2610d2e601054620f424061248390919063ffffffff16565b610cae888888612664565b949350505050565b600a5490565b600b5460ff1690565b600b5460ff161515610dac576040805160e560020a62461bcd02815260206004820152601460248201527f42756e646c696e672069732064697361626c6564000000000000000000000000604482015290519081900360640190fd5b600a5415610e06576040805160e560020a62461bcd02815260206004820152602a6024820152600080516020613a3d8339815191526044820152600080516020613a1d833981519152606482015290519081900360840190fd5b60025415610eaa576040805160e560020a62461bcd02815260206004820152604660248201527f62756e646c654669727374546f6b656e733a2054686973206d6574686f64206360448201527f616e20626520757365642077697468207a65726f20746f74616c20737570706c60648201527f79206f6e6c790000000000000000000000000000000000000000000000000000608482015290519081900360a40190fd5b610eb583838361284b565b505050565b6006546000908190600160a060020a03868116610100909204161415610f0657600780546000198101908110610eec57fe5b600091825260209091200154600160a060020a0316610f08565b845b9050610f15818585612ae6565b95945050505050565b600054600160a060020a03163314610f3557600080fd5b600b5460ff161515610f91576040805160e560020a62461bcd02815260206004820152601c60248201527f42756e646c696e6720697320616c72656164792064697361626c656400000000604482015290519081900360640190fd5b600b805460ff19169055604080516000815290517fcd495a5e98995df10f680f215ceaac5420ab5f1e24457a3fcdf19a91ad1079f19181900360200190a1565b60065460ff1681565b6000610fe684846116fe565b50600654604080517f1cb9ce63000000000000000000000000000000000000000000000000000000008152600160a060020a03878116600483019081526024830193845286516044840152865161010090950490911693631cb9ce639334938a93899390929160640190602085019080838360005b8381101561107357818101518382015260200161105b565b50505050905090810190601f1680156110a05780820380516001836020036101000a031916815260200191505b5093505050506020604051808303818588803b1580156110bf57600080fd5b505af11580156110d3573d6000803e3d6000fd5b50505050506040513d60208110156110ea57600080fd5b505115156110f757600080fd5b5060019392505050565b60065460ff1615611181576040805160e560020a62461bcd028152602060048201526024808201527f636f6e7374727563746f723a20646563696d616c732073686f756c642062652060448201527f7a65726f00000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600060ff821611611202576040805160e560020a62461bcd02815260206004820152602960248201527f636f6e7374727563746f723a205f646563696d616c732073686f756c64206e6f60448201527f74206265207a65726f0000000000000000000000000000000000000000000000606482015290519081900360840190fd5b8251600010611281576040805160e560020a62461bcd02815260206004820152602560248201527f636f6e7374727563746f723a206e616d652073686f756c64206e6f742062652060448201527f656d707479000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b8151600010611300576040805160e560020a62461bcd02815260206004820152602760248201527f636f6e7374727563746f723a2073796d626f6c2073686f756c64206e6f74206260448201527f6520656d70747900000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b835160021115611380576040805160e560020a62461bcd02815260206004820152603260248201527f436f6e747261637420646f6573206e6f7420737570706f7274206c657373207460448201527f68616e203220696e6e657220746f6b656e730000000000000000000000000000606482015290519081900360840190fd5b82516113939060049060208601906138c9565b5081516113a79060059060208501906138c9565b506006805460ff191660ff831617905583516113ca906009906020870190613943565b506113f47fd5c368b600000000000000000000000000000000000000000000000000000000612c4b565b50505050565b600f5490565b600060098281548110151561141157fe5b600091825260209091200154600160a060020a031692915050565b6000610f15858585856000610c55565b336000908152600360209081526040808320600160a060020a038616845290915281205480831061149057336000908152600360209081526040808320600160a060020a03881684529091528120556114c5565b6114a0818463ffffffff61248316565b336000908152600360209081526040808320600160a060020a03891684529091529020555b336000818152600360209081526040808320600160a060020a0389168085529083529281902054815190815290519293927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929181900390910190a35060019392505050565b611539858585856012612c87565b5050505050565b600160a060020a031660009081526001602052604090205490565b600054600160a060020a0316331461157257600080fd5b6207a1208111156115f3576040805160e560020a62461bcd02815260206004820152603f60248201527f736574526566657272616c4665653a206665652073686f756c64206265206e6f60448201527f742067726561746572207468616e20353025206f66206368616e676546656500606482015290519081900360840190fd5b601155565b600054600160a060020a0316331461160f57600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a26000805473ffffffffffffffffffffffffffffffffffffffff19169055565b600e5460ff1690565b60115490565b600054600160a060020a031681565b6005805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610be65780601f10610bbb57610100808354040283529160200191610be6565b60095490565b600160a060020a03166000908152600c602052604090205490565b3360009081526001602052604081205482111561171a57600080fd5b600160a060020a038316151561172f57600080fd5b3360009081526001602052604090205461174f908363ffffffff61248316565b3360009081526001602052604080822092909255600160a060020a03851681522054611781908363ffffffff612f1216565b600160a060020a038416600081815260016020908152604091829020939093558051858152905191923392600080516020613a5d8339815191529281900390910190a350600192915050565b600a5415611827576040805160e560020a62461bcd02815260206004820152602a6024820152600080516020613a3d8339815191526044820152600080516020613a1d833981519152606482015290519081900360840190fd5b61188c8282600980548060200260200160405190810160405280929190818152602001828054801561188257602002820191906000526020600020905b8154600160a060020a03168152600190910190602001808311611864575b5050505050611a44565b5050565b6000611937620f4240610ca26118b4600f54620f4240612f1290919063ffffffff16565b6040805160e060020a6370a082310281523060048201529051600160a060020a038b16916370a082319160248083019260209291908290030181600087803b1580156118ff57600080fd5b505af1158015611913573d6000803e3d6000fd5b505050506040513d602081101561192957600080fd5b50519063ffffffff61249516565b90506119468686868686612f1f565b6040805160e060020a6370a0823102815230600482015290518291600160a060020a038816916370a08231916024808201926020929091908290030181600087803b15801561199457600080fd5b505af11580156119a8573d6000803e3d6000fd5b505050506040513d60208110156119be57600080fd5b50511015611a3c576040805160e560020a62461bcd02815260206004820152602b60248201527f6c656e643a20746f6b656e73206d7573742062652072657475726e656420776960448201527f7468206c656e6420666565000000000000000000000000000000000000000000606482015290519081900360840190fd5b505050505050565b600a5415611a9e576040805160e560020a62461bcd02815260206004820152602a6024820152600080516020613a3d8339815191526044820152600080516020613a1d833981519152606482015290519081900360840190fd5b610eb583838361320e565b600054600160a060020a03163314611ac057600080fd5b617530811115611b40576040805160e560020a62461bcd02815260206004820152602f60248201527f7365744368616e67654665653a206665652073686f756c64206265206e6f742060448201527f67726561746572207468616e2033250000000000000000000000000000000000606482015290519081900360840190fd5b601055565b600054600160a060020a03163314611b5c57600080fd5b600e5460ff161515611bb8576040805160e560020a62461bcd02815260206004820152601c60248201527f4368616e6765732061726520616c72656164792064697361626c656400000000604482015290519081900360640190fd5b600e805460ff191690556040517f5fe2f33cb1aaeac88078a7189134f6b75107e50ba04e8324db46c533d760519890600090a1565b6007805460018101825560009182527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68801805473ffffffffffffffffffffffffffffffffffffffff191633179055611c458484610bee565b50600654604080517f1cb9ce63000000000000000000000000000000000000000000000000000000008152600160a060020a03878116600483019081526024830193845286516044840152865161010090950490911693631cb9ce639334938a93899390929160640190602085019080838360005b83811015611cd2578181015183820152602001611cba565b50505050905090810190601f168015611cff5780820380516001836020036101000a031916815260200191505b5093505050506020604051808303818588803b158015611d1e57600080fd5b505af1158015611d32573d6000803e3d6000fd5b50505050506040513d6020811015611d4957600080fd5b50511515611d5657600080fd5b600780546000190190611d6990826139b1565b506001949350505050565b336000908152600360209081526040808320600160a060020a0386168452909152812054611da8908363ffffffff612f1216565b336000818152600360209081526040808320600160a060020a0389168085529083529281902085905580519485525191937f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925929081900390910190a350600192915050565b600160a060020a03918216600090815260036020908152604080832093909416825291909152205490565b600054600160a060020a03163314611e4f57600080fd5b617530811115611ecf576040805160e560020a62461bcd02815260206004820152602d60248201527f7365744c656e644665653a206665652073686f756c64206265206e6f7420677260448201527f6561746572207468616e20332500000000000000000000000000000000000000606482015290519081900360840190fd5b600f55565b7f81624e240000000000000000000000000000000000000000000000000000000081565b7fd5c368b60000000000000000000000000000000000000000000000000000000081565b600b5460609060009060ff161515611f7e576040805160e560020a62461bcd02815260206004820152601460248201527f42756e646c696e672069732064697361626c6564000000000000000000000000604482015290519081900360640190fd5b600a5415611fd8576040805160e560020a62461bcd02815260206004820152602a6024820152600080516020613a3d8339815191526044820152600080516020613a1d833981519152606482015290519081900360840190fd5b6002541515612057576040805160e560020a62461bcd02815260206004820152603760248201527f54686973206d6574686f642063616e20626520757365642077697468206e6f6e60448201527f207a65726f20746f74616c20737570706c79206f6e6c79000000000000000000606482015290519081900360840190fd5b600954604080518281526020808402820101909152908015612083578160200160208202803883390190505b509150600090505b60095481101561212857612108600254610ca2856009858154811015156120ae57fe5b60009182526020808320909101546040805160e060020a6370a082310281523060048201529051600160a060020a03909216936370a082319360248084019491939192918390030190829087803b1580156118ff57600080fd5b828281518110151561211657fe5b6020908102909101015260010161208b565b6113f484848461284b565b600054600160a060020a0316331461214a57600080fd5b600b5460ff16156121a5576040805160e560020a62461bcd02815260206004820152601b60248201527f42756e646c696e6720697320616c726561647920656e61626c65640000000000604482015290519081900360640190fd5b600b805460ff1916600190811790915560408051918252517fcd495a5e98995df10f680f215ceaac5420ab5f1e24457a3fcdf19a91ad1079f19181900360200190a1565b600054600160a060020a0316331461220057600080fd5b612209816134d0565b50565b620f424081565b6006546101009004600160a060020a031690565b600e5460009060ff1615156122ac576040805160e560020a62461bcd02815260206004820152603960248201527f4f7065726174696f6e2063616e277420626520706572666f726d65642062656360448201527f61757365206368616e676573206172652064697361626c656400000000000000606482015290519081900360840190fd5b600a5415612306576040805160e560020a62461bcd02815260206004820152602a6024820152600080516020613a3d8339815191526044820152600080516020613a1d833981519152606482015290519081900360840190fd5b612311858585610d0a565b90506000811161236b576040805160e560020a62461bcd02815260206004820152601960248201527f5468652072657475726e20616d6f756e74206973207a65726f00000000000000604482015290519081900360640190fd5b818110156123e9576040805160e560020a62461bcd02815260206004820152602e60248201527f5468652072657475726e20616d6f756e74206973206c657373207468616e206d60448201527f696e52657475726e2076616c7565000000000000000000000000000000000000606482015290519081900360840190fd5b612404600160a060020a03861633308663ffffffff61354d16565b61241e600160a060020a038516338363ffffffff6124d316565b33600160a060020a031684600160a060020a031686600160a060020a03167f24cee3d6b5651a987362aa6216b9d34a39212f0f1967dfd48c2c3a4fc3c576dc8685604051808381526020018281526020019250505060405180910390a4949350505050565b60008282111561248f57fe5b50900390565b60008215156124a657506000610c4f565b508181028183828115156124b657fe5b0414610c4f57fe5b600081838115156124cb57fe5b049392505050565b6000808211156113f4576040805160e060020a6370a082310281523060048201529051600160a060020a038616916370a082319160248083019260209291908290030181600087803b15801561252857600080fd5b505af115801561253c573d6000803e3d6000fd5b505050506040513d602081101561255257600080fd5b505190506125618484846136ff565b50612572818363ffffffff61248316565b6040805160e060020a6370a082310281523060048201529051600160a060020a038716916370a082319160248083019260209291908290030181600087803b1580156125bd57600080fd5b505af11580156125d1573d6000803e3d6000fd5b505050506040513d60208110156125e757600080fd5b5051146113f4576040805160e560020a62461bcd02815260206004820152602b60248201527f636865636b65645472616e736665723a2046696e616c2062616c616e6365206460448201527f69646e2774206d61746368000000000000000000000000000000000000000000606482015290519081900360840190fd5b600160a060020a0383166000908152600c602052604081205481908190811080156126a55750600160a060020a0385166000908152600c6020526040812054115b80156126c3575084600160a060020a031686600160a060020a031614155b15612842576040805160e060020a6370a082310281523060048201529051600160a060020a038816916370a082319160248083019260209291908290030181600087803b15801561271357600080fd5b505af1158015612727573d6000803e3d6000fd5b505050506040513d602081101561273d57600080fd5b50516040805160e060020a6370a082310281523060048201529051919350600160a060020a038716916370a08231916024808201926020929091908290030181600087803b15801561278e57600080fd5b505af11580156127a2573d6000803e3d6000fd5b505050506040513d60208110156127b857600080fd5b5051600160a060020a038087166000908152600c602052604080822054600d54938b16835291205492935061283f9261281292610cae91879161280691610ca2908c9063ffffffff61249516565b9063ffffffff612f1216565b600160a060020a0388166000908152600c6020526040902054610ca290610cae888663ffffffff61249516565b92505b50509392505050565b60008215156128ca576040805160e560020a62461bcd02815260206004820152602260248201527f42756e646c696e6720616d6f756e742073686f756c64206265206e6f6e2d7a6560448201527f726f000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b81516009541461294a576040805160e560020a62461bcd02815260206004820152603960248201527f4c656e67687473206f66205f746f6b656e7320616e6420746f6b656e416d6f7560448201527f6e74732061727261792073686f756c6420626520657175616c00000000000000606482015290519081900360840190fd5b5060005b600954811015612a1d57818181518110151561296657fe5b6020908102909101015115156129c6576040805160e560020a62461bcd02815260206004820152601f60248201527f546f6b656e20616d6f756e742073686f756c64206265206e6f6e2d7a65726f00604482015290519081900360640190fd5b612a15333084848151811015156129d957fe5b906020019060200201516009858154811015156129f257fe5b600091825260209091200154600160a060020a031692919063ffffffff61354d16565b60010161294e565b600254612a30908463ffffffff612f1216565b600255600160a060020a038416600090815260016020526040902054612a5c908463ffffffff612f1216565b600160a060020a0385166000818152600160209081526040918290209390935580518681529051919233927f6401d28c11d9f5749b7d2848c2af727680ae93ed2c51ac22e65ed498fb8dcb419281900390910190a3604080518481529051600160a060020a03861691600091600080516020613a5d8339815191529181900360200190a350505050565b600160a060020a038316600090815260016020526040812054821115612b0b57600080fd5b600160a060020a0384166000908152600360209081526040808320338452909152902054821115612b3b57600080fd5b600160a060020a0383161515612b5057600080fd5b600160a060020a038416600090815260016020526040902054612b79908363ffffffff61248316565b600160a060020a038086166000908152600160205260408082209390935590851681522054612bae908363ffffffff612f1216565b600160a060020a038085166000908152600160209081526040808320949094559187168152600382528281203382529091522054612bf2908363ffffffff61248316565b600160a060020a0380861660008181526003602090815260408083203384528252918290209490945580518681529051928716939192600080516020613a5d833981519152929181900390910190a35060019392505050565b600160e060020a03198082161415612c6257600080fd5b600160e060020a0319166000908152600860205260409020805460ff19166001179055565b600080612c9687868686611101565b8651865114612d15576040805160e560020a62461bcd02815260206004820152603860248201527f4c656e67687473206f6620746f6b656e7320616e6420746f6b656e576569676860448201527f74732061727261792073686f756c6420626520657175616c0000000000000000606482015290519081900360840190fd5b5060009050805b8651811015612edb578581815181101515612d3357fe5b602090810290910101511515612db9576040805160e560020a62461bcd02815260206004820152603060248201527f54686520746f6b656e576569676874732061727261792073686f756c64206e6f60448201527f7420636f6e7461696e73207a65726f7300000000000000000000000000000000606482015290519081900360840190fd5b600c60008883815181101515612dcb57fe5b6020908102909101810151600160a060020a031682528101919091526040016000205415612e43576040805160e560020a62461bcd02815260206004820181905260248201527f54686520746f6b656e732061727261792068617665206475706c696361746573604482015290519081900360640190fd5b8581815181101515612e5157fe5b90602001906020020151600c60008984815181101515612e6d57fe5b6020908102909101810151600160a060020a0316825281019190915260400160002055811580612eb35750818682815181101515612ea757fe5b90602001906020020151105b15612ed3578581815181101515612ec657fe5b9060200190602002015191505b600101612d1c565b600d829055612f097f81624e2400000000000000000000000000000000000000000000000000000000612c4b565b50505050505050565b81810182811015610c4f57fe5b6040805160e060020a6370a082310281523060048201529051600091600160a060020a038716916370a082319160248082019260209290919082900301818787803b158015612f6d57600080fd5b505af1158015612f81573d6000803e3d6000fd5b505050506040513d6020811015612f9757600080fd5b50519050612fb5600160a060020a038616878663ffffffff6136ff16565b50600a80546001019055612fc7612213565b600160a060020a0316631cb9ce633485856040518463ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561303f578181015183820152602001613027565b50505050905090810190601f16801561306c5780820380516001836020036101000a031916815260200191505b5093505050506020604051808303818588803b15801561308b57600080fd5b505af115801561309f573d6000803e3d6000fd5b50505050506040513d60208110156130b657600080fd5b5051151561310e576040805160e560020a62461bcd02815260206004820152601b60248201527f6c656e643a206172626974726172792063616c6c206661696c65640000000000604482015290519081900360640190fd5b600a80546000190190556040805160e060020a6370a0823102815230600482015290518291600160a060020a038816916370a08231916024808201926020929091908290030181600087803b15801561316657600080fd5b505af115801561317a573d6000803e3d6000fd5b505050506040513d602081101561319057600080fd5b50511015611a3c576040805160e560020a62461bcd02815260206004820152602360248201527f6c656e643a206c656e64656420746f6b656e206d75737420626520726566696c60448201527f6c65640000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60008060008060008551111515613295576040805160e560020a62461bcd02815260206004820152602260248201527f4172726179206f6620736f6d65546f6b656e732063616e277420626520656d7060448201527f7479000000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b600254336000908152600160205260409020549094506132bb908763ffffffff61248316565b336000908152600160205260409020556132db848763ffffffff61248316565b600255604080518781529051600160a060020a0389169133917f8c85614f24f81c7b85c9837ab8277cfc5062dea12393fe90c757220926b07a7b9181900360200190a36040805187815290516000913391600080516020613a5d8339815191529181900360200190a3600092505b8451831015612f0957600091505b8282101561342857848281518110151561336d57fe5b90602001906020020151600160a060020a0316858481518110151561338e57fe5b60209081029091010151600160a060020a0316141561341d576040805160e560020a62461bcd02815260206004820152603b60248201527f756e62756e646c65536f6d653a2073686f756c64206e6f7420756e62756e646c60448201527f652073616d6520746f6b656e206d756c7469706c652074696d65730000000000606482015290519081900360840190fd5b600190910190613357565b61349084610ca288888781518110151561343e57fe5b60209081029091018101516040805160e060020a6370a082310281523060048201529051600160a060020a03909216926370a08231926024808401938290030181600087803b1580156118ff57600080fd5b90506134c5878287868151811015156134a557fe5b60209081029091010151600160a060020a0316919063ffffffff6124d316565b600190920191613349565b600160a060020a03811615156134e557600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a36000805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b6000808211156115395784600160a060020a03166370a08231846040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b1580156135b257600080fd5b505af11580156135c6573d6000803e3d6000fd5b505050506040513d60208110156135dc57600080fd5b505190506135ec858585856137bb565b506135fd818363ffffffff612f1216565b85600160a060020a03166370a08231856040518263ffffffff1660e060020a0281526004018082600160a060020a0316600160a060020a03168152602001915050602060405180830381600087803b15801561365857600080fd5b505af115801561366c573d6000803e3d6000fd5b505050506040513d602081101561368257600080fd5b505114611539576040805160e560020a62461bcd02815260206004820152602b60248201527f636865636b65645472616e736665723a2046696e616c2062616c616e6365206460448201527f69646e2774206d61746368000000000000000000000000000000000000000000606482015290519081900360840190fd5b600061370a84613892565b151561371557600080fd5b83600160a060020a031660405180807f7472616e7366657228616464726573732c75696e7432353629000000000000008152506019019050604051809103902060e060020a900484846040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a03168152602001828152602001925050506000604051808303816000875af19250505015156137b357600080fd5b610d3961389a565b60006137c685613892565b15156137d157600080fd5b604080517f7472616e7366657246726f6d28616464726573732c616464726573732c75696e81527f74323536290000000000000000000000000000000000000000000000000000006020820152815190819003602501812063ffffffff60e060020a918290049081169091028252600160a060020a0387811660048401528681166024840152604483018690529251928816929091606480820192600092909190829003018183875af192505050151561388a57600080fd5b610f1561389a565b6000903b1190565b60003d80156138b057602081146138b957600080fd5b600191506138c5565b60206000803e60005191505b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061390a57805160ff1916838001178555613937565b82800160010185558215613937579182015b8281111561393757825182559160200191906001019061391c565b506138c59291506139d1565b8280548282559060005260206000209081019282156139a5579160200282015b828111156139a5578251825473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a03909116178255602090920191600190910190613963565b506138c59291506139eb565b815481835581811115610eb557600083815260209020610eb59181019083015b610b3e91905b808211156138c557600081556001016139d7565b610b3e91905b808211156138c557805473ffffffffffffffffffffffffffffffffffffffff191681556001016139f156006c65206c656e64696e67000000000000000000000000000000000000000000004f7065726174696f6e2063616e277420626520706572666f726d656420776869ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa165627a7a723058208f9721030d60da9e6d1e14a3bd46bae277e5c793dbdd1f450c16d1073a64b5b00029

Swarm Source

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