Contract Overview
Balance: 0.504804737 Ether
Ether Value: $58.43 (@ $115.75/ETH)
Transactions: 59 txns
Token Tracker: �y� TOS05 (�y� TOS05)
Misc:
Address Watch: Add To Watch List
Contract Creator: 0x40e4af98aca710ddbb86a4f7d2d781906d3d108cat txn 0x014914729f8cb8e03779e94cb64cc6ade9bfd29f8e0f607c1c6aece8e70b2d9f
 Latest 25 transactions from a total of 59 transactions

TxHash Age From To Value [TxFee]
0x39f7084eb1b4f54bb202249a704cf88e56e08a50894e6df5b9171bb48a29458186 days 22 hrs ago0x40e4af98aca710ddbb86a4f7d2d781906d3d108c  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff0 Ether0.00140179
0xc325d95b827366b94d0e4112567e8050d6c1d0878f25988e3fe7308d777dd32c86 days 22 hrs ago0x40e4af98aca710ddbb86a4f7d2d781906d3d108c  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff0 Ether0.001681764
0xd5cfbe03acb05d0b418d7a39a5015bdd1e172f4422981525f1db792c61a70edf86 days 22 hrs ago0x40e4af98aca710ddbb86a4f7d2d781906d3d108c  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff0 Ether0.00140179
0x334cff48bb6aab0f0bdfe146d88a9a64fb2bd73f7063c313af96c5f596a9fbc386 days 22 hrs ago0x40e4af98aca710ddbb86a4f7d2d781906d3d108c  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff0 Ether0.00140179
0x2211419622fdaa5da7157af61ca62b10ac28ba09b8b378e683f07641b2f5e26186 days 22 hrs ago0x40e4af98aca710ddbb86a4f7d2d781906d3d108c  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff0 Ether0.00140179
0x052d1d7ea7334a7f8117633bb081dd85adb6ce0e06fefe26946b3688fcb8db0090 days 53 mins ago0x90a285f0ce4c56d234af78194182d212eb135389  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff0.004804737 Ether0.002161512
0x2152b734108da7518b9bbecaa20f5a3d994b0edd0f685154bed4c1ca71ba49b590 days 1 hr ago0x40e4af98aca710ddbb86a4f7d2d781906d3d108c  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff0 Ether0.004176225
0x1a677ce054667593ef220268675264032c6ad65117fbdb9742611c1f76495edc90 days 1 hr ago0x40e4af98aca710ddbb86a4f7d2d781906d3d108c  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff0 Ether0.000493935
0x2979814d45cc046aa428455e4b81e5d39f1173761b218a1e1904a88c6654b73b90 days 1 hr ago0x90a285f0ce4c56d234af78194182d212eb135389  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff154.35 Ether0.00786995
0xf4e0e888b39df165d54f11f0ba88f303489d2c83f92c677857af3733fb81788790 days 1 hr ago0x40e4af98aca710ddbb86a4f7d2d781906d3d108c  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff0 Ether0.000493935
0xeca17d2f78a69034b05f943935d930100a82580753bb1eb15984140fa4da84d690 days 1 hr ago0x40e4af98aca710ddbb86a4f7d2d781906d3d108c  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff0 Ether0.004177185
0xc0e20ad442b8a613a1434d96a886ed9371a6b564922df434cb018c1f1b3db88990 days 1 hr ago0x40e4af98aca710ddbb86a4f7d2d781906d3d108c  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff0 Ether0.005013774
0xb913e5610616bebf5bf96713c54ec93c5f5a243033630ba59e3f3fcd29482b1290 days 1 hr ago0x40e4af98aca710ddbb86a4f7d2d781906d3d108c  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff0 Ether0.005013774
0x540932b2119756f087833b035135f38229c1d3ea2c0626beb38a9824b480b1fe90 days 1 hr ago0x40e4af98aca710ddbb86a4f7d2d781906d3d108c  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff0 Ether0.005012622
0x66de069b7c81283ec524b15aae8e31d32d22e7a4ecb16f992bfb4a5147636b0090 days 1 hr ago0x40e4af98aca710ddbb86a4f7d2d781906d3d108c  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff0 Ether0.005013774
0xffe357aec2082789113e8410148b2b30c5433a0ade3760f89a7b2b590582f22090 days 1 hr ago0x40e4af98aca710ddbb86a4f7d2d781906d3d108c  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff0 Ether0.004177185
0x5223e7b09e95ff597f9a6eb046648a784957e091ad35c44357120b3765cbedeb90 days 1 hr ago0x632210f14d3639cdce9117e7b86312c14c8a37e6  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff4 Ether0.007779832
0xbf9a201e1225c767a58d5af96f4d1218cac896738dd71517dcfe831a61e0459890 days 1 hr ago0xe9b938e5f453065e266ab0bac83ae39607dbe03f  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff10 Ether0.00314798
0x61f37cdd08774f4f8886eb8f0f2da615b8fb1027ed623c49a99872f91183690a90 days 3 hrs ago0x7f870f699b61323d360a1c8ba9e729d032f10685  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff2.987066058 Ether0.012906718
0x3d1af00e74a49c70caf711dce5677a2ed394d971d093d736ac168ff6ea5f5e4a90 days 4 hrs ago0xcd2b663bb04c151d2d374f3960377605825b2b6b  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff1.35 Ether0.012906718
0x6993ad82dd547b9f4319475f35cd6c196e87d9b6f40c25e6e5da4e176642776490 days 11 hrs ago0x40e4af98aca710ddbb86a4f7d2d781906d3d108c  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff0 Ether0.001671318
0x4228fb5b028e31311f296ae45d9f55d0c38cb0357442535d0e9aeef53e5816ff90 days 11 hrs ago0x40e4af98aca710ddbb86a4f7d2d781906d3d108c  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff0 Ether0.001671318
0xbd80c808cac5f2bbffc86680613a18620d6efee7cda5ced4bbf4e75d25a7c18d90 days 11 hrs ago0x40e4af98aca710ddbb86a4f7d2d781906d3d108c  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff0 Ether0.001671318
0xafe390727d41e018cc90a0e585cd124851cb880f65af6151860e5a526584ef7990 days 11 hrs ago0x40e4af98aca710ddbb86a4f7d2d781906d3d108c  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff0 Ether0.001671318
0x234a84244936ddcdc3d44ed3a3c7ede6a251393a25e86583501699bdacc2a2a090 days 11 hrs ago0x40e4af98aca710ddbb86a4f7d2d781906d3d108c  IN   0x8de429fe7d969c3075fd72fd87b455b060933cff0 Ether0.001671318
[ Download CSV Export  ] 
 Internal Transactions as a result of Contract Execution
 Latest 14 Internal Transactions

ParentTxHash Block Age From To Value
0x2979814d45cc046aa428455e4b81e5d39f1173761b218a1e1904a88c6654b73b658629590 days 1 hr ago0x8de429fe7d969c3075fd72fd87b455b060933cff0x74e6acf300e8c8d8ef7c1f85d2589fc1fcc8a500154.35 Ether
0x5223e7b09e95ff597f9a6eb046648a784957e091ad35c44357120b3765cbedeb658620390 days 1 hr ago0x8de429fe7d969c3075fd72fd87b455b060933cff0x74e6acf300e8c8d8ef7c1f85d2589fc1fcc8a5004 Ether
0xbf9a201e1225c767a58d5af96f4d1218cac896738dd71517dcfe831a61e04598658614790 days 1 hr ago0x8de429fe7d969c3075fd72fd87b455b060933cff0x74e6acf300e8c8d8ef7c1f85d2589fc1fcc8a50010 Ether
0x61f37cdd08774f4f8886eb8f0f2da615b8fb1027ed623c49a99872f91183690a658571390 days 3 hrs ago0x8de429fe7d969c3075fd72fd87b455b060933cff0x74e6acf300e8c8d8ef7c1f85d2589fc1fcc8a5002.987066058 Ether
0x3d1af00e74a49c70caf711dce5677a2ed394d971d093d736ac168ff6ea5f5e4a658534790 days 4 hrs ago0x8de429fe7d969c3075fd72fd87b455b060933cff0x74e6acf300e8c8d8ef7c1f85d2589fc1fcc8a5001.35 Ether
0x685386f83cd1d95aa58d06cf8a7787f7d3be5e07b837171758b0a983da8fda86658333390 days 12 hrs ago0x8de429fe7d969c3075fd72fd87b455b060933cff0x74e6acf300e8c8d8ef7c1f85d2589fc1fcc8a5002,835 Ether
0x22eeb09c73eaa62c79fc613d7a377786aded3af28c63ffd3027f94a8d14ad82f658318490 days 13 hrs ago0x8de429fe7d969c3075fd72fd87b455b060933cff0x74e6acf300e8c8d8ef7c1f85d2589fc1fcc8a5002 Ether
0x5c340eb0c4f5d4f928ba73e1bd6f2934c78abc966a8f721bfb86530323189312658253590 days 15 hrs ago0x8de429fe7d969c3075fd72fd87b455b060933cff0x74e6acf300e8c8d8ef7c1f85d2589fc1fcc8a50012.239 Ether
0xfa547c8f3a9b03b45a21d4714acc3cb68450809ef97830d33cc3454c03264130658238790 days 16 hrs ago0x8de429fe7d969c3075fd72fd87b455b060933cff0x74e6acf300e8c8d8ef7c1f85d2589fc1fcc8a50011.44 Ether
0x95103daac6a812f92cc8204802a14a726b710a14c928cef880c417ec44b3de4c657938491 days 4 hrs ago0x8de429fe7d969c3075fd72fd87b455b060933cff0x74e6acf300e8c8d8ef7c1f85d2589fc1fcc8a50017.92 Ether
0x11a4af9431e493285094f183fa84dc957a0f2e8fc5a64961cd3ac116274b1cbd657551791 days 19 hrs ago0x8de429fe7d969c3075fd72fd87b455b060933cff0x74e6acf300e8c8d8ef7c1f85d2589fc1fcc8a5001,470 Ether
0x6b506e4adc25218a0e595b104e836d3f18c4f67430ebca59ac8a7353cdc8a417657046692 days 15 hrs ago0x8de429fe7d969c3075fd72fd87b455b060933cff0x74e6acf300e8c8d8ef7c1f85d2589fc1fcc8a500100 Ether
0xbd16e6e03220bd2387eef353e490fb8eb7d5d691586635927d31eb36b4a4bb7e656820292 days 23 hrs ago0x8de429fe7d969c3075fd72fd87b455b060933cff0x74e6acf300e8c8d8ef7c1f85d2589fc1fcc8a5001.041835336 Ether
0x64e35cff77eb8d997fc3eb56e8cd737dcbe82cd22335d68a90d3e6db4060646b656797693 days 50 mins ago0x8de429fe7d969c3075fd72fd87b455b060933cff0x74e6acf300e8c8d8ef7c1f85d2589fc1fcc8a5000.001 Ether
[ Download CSV Export  ] 
Warning: The Compiled Contract might be susceptible to ExpExponentCleanup (medium/high-severity), EventStructWrongData (very low-severity) SolidityCompiler Bugs.

Contract Source Code Verified (Exact Match)
Contract Name: Tokensale
Compiler Text: v0.4.24+commit.e67f0147
Optimization Enabled: No
Runs (Optimiser):  200



  Contract Source Code   Find Similiar Contracts

/**
 * Tokensale.sol
 * MPS Token (Mt Pelerin Share) token sale : private round.

 * More info about MPS : https://github.com/MtPelerin/MtPelerin-share-MPS

 * The unflattened code is available through this github tag:
 * https://github.com/MtPelerin/MtPelerin-protocol/tree/etherscan-verify-batch-1

 * @notice Copyright © 2016 - 2018 Mt Pelerin Group SA - All Rights Reserved

 * @notice All matters regarding the intellectual property of this code 
 * @notice or software are subject to Swiss Law without reference to its 
 * @notice conflicts of law rules.

 * @notice License for each contract is available in the respective file
 * @notice or in the LICENSE.md file.
 * @notice https://github.com/MtPelerin/

 * @notice Code by OpenZeppelin is copyrighted and licensed on their repository:
 * @notice https://github.com/OpenZeppelin/openzeppelin-solidity
 */

pragma solidity ^0.4.24;

// File: contracts/interface/IUserRegistry.sol

/**
 * @title IUserRegistry
 * @dev IUserRegistry interface
 * @author Cyril Lapinte - <[email protected]>
 *
 * @notice Copyright © 2016 - 2018 Mt Pelerin Group SA - All Rights Reserved
 * @notice Please refer to the top of this file for the license.
 **/
contract IUserRegistry {

  function registerManyUsers(address[] _addresses, uint256 _validUntilTime)
    public;

  function attachManyAddresses(uint256[] _userIds, address[] _addresses)
    public;

  function detachManyAddresses(address[] _addresses)
    public;

  function userCount() public view returns (uint256);
  function userId(address _address) public view returns (uint256);
  function addressConfirmed(address _address) public view returns (bool);
  function validUntilTime(uint256 _userId) public view returns (uint256);
  function suspended(uint256 _userId) public view returns (bool);
  function extended(uint256 _userId, uint256 _key)
    public view returns (uint256);

  function isAddressValid(address _address) public view returns (bool);
  function isValid(uint256 _userId) public view returns (bool);

  function registerUser(address _address, uint256 _validUntilTime) public;
  function attachAddress(uint256 _userId, address _address) public;
  function confirmSelf() public;
  function detachAddress(address _address) public;
  function detachSelf() public;
  function detachSelfAddress(address _address) public;
  function suspendUser(uint256 _userId) public;
  function unsuspendUser(uint256 _userId) public;
  function suspendManyUsers(uint256[] _userIds) public;
  function unsuspendManyUsers(uint256[] _userIds) public;
  function updateUser(uint256 _userId, uint256 _validUntil, bool _suspended)
    public;

  function updateManyUsers(
    uint256[] _userIds,
    uint256 _validUntil,
    bool _suspended) public;

  function updateUserExtended(uint256 _userId, uint256 _key, uint256 _value)
    public;

  function updateManyUsersExtended(
    uint256[] _userIds,
    uint256 _key,
    uint256 _value) public;
}

// File: contracts/interface/IRatesProvider.sol

/**
 * @title IRatesProvider
 * @dev IRatesProvider interface
 *
 * @author Cyril Lapinte - <[email protected]>
 *
 * @notice Copyright © 2016 - 2018 Mt Pelerin Group SA - All Rights Reserved
 * @notice Please refer to the top of this file for the license.
 */
contract IRatesProvider {
  function rateWEIPerCHFCent() public view returns (uint256);
  function convertWEIToCHFCent(uint256 _amountWEI)
    public view returns (uint256);

  function convertCHFCentToWEI(uint256 _amountCHFCent)
    public view returns (uint256);
}

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

/**
 * @title ERC20Basic
 * @dev Simpler version of ERC20 interface
 * @dev 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: contracts/zeppelin/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: contracts/interface/ITokensale.sol

/**
 * @title ITokensale
 * @dev ITokensale interface
 *
 * @author Cyril Lapinte - <[email protected]>
 *
 * @notice Copyright © 2016 - 2018 Mt Pelerin Group SA - All Rights Reserved
 * @notice Please refer to the top of this file for the license.
 */
contract ITokensale {

  function () external payable;

  // Minimal Auto Withdraw must be allow the nominal price
  // to ensure enough remains on the balance to refund the investors
  uint256 constant MINIMAL_AUTO_WITHDRAW = 0.5 ether;
  uint256 constant MINIMAL_BALANCE = 0.5 ether;
  uint256 constant BASE_PRICE_CHF_CENT = 500;

  function minimalAutoWithdraw() public view returns (uint256);
  function minimalBalance() public view returns (uint256);
  function basePriceCHFCent() public view returns (uint256);

  /* General sale details */
  function token() public view returns (ERC20);
  function vaultETH() public view returns (address);
  function vaultERC20() public view returns (address);
  function userRegistry() public view returns (IUserRegistry);
  function ratesProvider() public view returns (IRatesProvider);
  function sharePurchaseAgreementHash() public view returns (bytes32);

  /* Sale status */
  function startAt() public view returns (uint256);
  function endAt() public view returns (uint256);
  function raisedETH() public view returns (uint256);
  function raisedCHF() public view returns (uint256);
  function totalRaisedCHF() public view returns (uint256);
  function refundedETH() public view returns (uint256);
  function availableSupply() public view returns (uint256);

  /* Investor specific attributes */
  function investorUnspentETH(uint256 _investorId)
    public view returns (uint256);

  function investorInvestedCHF(uint256 _investorId)
    public view returns (uint256);

  function investorAcceptedSPA(uint256 _investorId)
    public view returns (bool);

  function investorAllocations(uint256 _investorId)
    public view returns (uint256);

  function investorTokens(uint256 _investorId) public view returns (uint256);
  function investorCount() public view returns (uint256);

  /* Share Purchase Agreement */
  function defineSPA(bytes32 _sharePurchaseAgreementHash)
    public returns (bool);

  function acceptSPA(bytes32 _sharePurchaseAgreementHash)
    public payable returns (bool);

  /* Investment */
  function investETH() public payable;
  function addOffChainInvestment(address _investor, uint256 _amountCHF)
    public;

  /* Schedule */
  function updateSchedule(uint256 _startAt, uint256 _endAt) public;

  /* Allocations admin */
  function allocateTokens(address _investor, uint256 _amount)
    public returns (bool);

  function allocateManyTokens(address[] _investors, uint256[] _amounts)
    public returns (bool);

  /* ETH administration */
  function fundETH() public payable;
  function refundManyUnspentETH(address[] _receivers) public;
  function refundUnspentETH(address _receiver) public;
  function withdrawETHFunds() public;
  function autoWithdrawETHFunds() private;

  event SalePurchaseAgreementHash(bytes32 sharePurchaseAgreement);
  event Allocation(
    uint256 investorId,
    uint256 tokens
  );
  event Investment(
    uint256 investorId,
    uint256 spentCHF
  );
  event ChangeETHCHF(
    address investor,
    uint256 amount,
    uint256 converted,
    uint256 rate
  );
  event FundETH(uint256 amount);
  event WithdrawETH(address receiver, uint256 amount);
}

// File: contracts/zeppelin/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/zeppelin/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.
   */
  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: contracts/Authority.sol

/**
 * @title Authority
 * @dev The Authority contract has an authority address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 * Authority means to represent a legal entity that is entitled to specific rights
 *
 * @author Cyril Lapinte - <[email protected]>
 *
 * @notice Copyright © 2016 - 2018 Mt Pelerin Group SA - All Rights Reserved
 * @notice Please refer to the top of this file for the license.
 *
 * Error messages
 * AU01: Message sender must be an authority
 */
contract Authority is Ownable {

  address authority;

  /**
   * @dev Throws if called by any account other than the authority.
   */
  modifier onlyAuthority {
    require(msg.sender == authority, "AU01");
    _;
  }

  /**
   * @dev return the address associated to the authority
   */
  function authorityAddress() public view returns (address) {
    return authority;
  }

  /**
   * @dev rdefines an authority
   * @param _name the authority name
   * @param _address the authority address.
   */
  function defineAuthority(string _name, address _address) public onlyOwner {
    emit AuthorityDefined(_name, _address);
    authority = _address;
  }

  event AuthorityDefined(
    string name,
    address _address
  );
}

// File: contracts/tokensale/Tokensale.sol

/**
 * @title Tokensale
 * @dev Tokensale interface
 *
 * @author Cyril Lapinte - <[email protected]>
 *
 * @notice Copyright © 2016 - 2018 Mt Pelerin Group SA - All Rights Reserved
 * @notice Please refer to the top of this file for the license.
 *
 * Error messages
 * TOS01: It must be before the sale is opened
 * TOS02: Sale must be open
 * TOS03: It must be before the sale is closed
 * TOS04: It must be after the sale is closed
 * TOS05: No data must be sent while sending ETH
 * TOS06: Share Purchase Agreement Hashes must match
 * TOS07: User/Investor must exist
 * TOS08: SPA must be accepted before any ETH investment
 * TOS09: Cannot update schedule once started
 * TOS10: Investor must exist
 * TOS11: Cannot allocate more tokens than available supply
 * TOS12: Length of investorIds and amounts arguments must match
 * TOS13: Investor must exist
 * TOS14: Must refund ETH unspent
 * TOS15: Must withdraw ETH to vaultETH
 * TOS16: Cannot invest onchain and offchain at the same time
 * TOS17: A ETHCHF rate must exist to invest
 * TOS18: User must be valid
 * TOS19: Cannot invest if no tokens are available
 * TOS20: Cannot unspend more CHF than BASE_TOKEN_PRICE_CHF
 * TOS21: Token transfer must be successful
 */
contract Tokensale is ITokensale, Authority {
  using SafeMath for uint256;

  /* General sale details */
  ERC20 public token;
  address public vaultETH;
  address public vaultERC20;
  IUserRegistry public userRegistry;
  IRatesProvider public ratesProvider;

  uint256 public minimalBalance = MINIMAL_BALANCE;
  bytes32 public sharePurchaseAgreementHash;

  uint256 public startAt = 4102441200;
  uint256 public endAt = 4102441200;
  uint256 public raisedETH;
  uint256 public raisedCHF;
  uint256 public totalRaisedCHF;
  uint256 public refundedETH;
  uint256 public allocatedTokens;

  struct Investor {
    uint256 unspentETH;
    uint256 investedCHF;
    bool acceptedSPA;
    uint256 allocations;
    uint256 tokens;
  }
  mapping(uint256 => Investor) investors;
  uint256 public investorCount;

  /**
   * @dev Throws after sale opening
   */
  modifier beforeSaleIsOpened {
    require(currentTime() < startAt, "TOS01");
    _;
  }

  /**
   * @dev Throws if sale is not open
   */
  modifier saleIsOpened {
    require(currentTime() >= startAt && currentTime() <= endAt, "TOS02");
    _;
  }

  /**
   * @dev Throws once the sale is closed
   */
  modifier beforeSaleIsClosed {
    require(currentTime() <= endAt, "TOS03");
    _;
  }

  /**
   * @dev constructor
   */
  constructor(
    ERC20 _token,
    IUserRegistry _userRegistry,
    IRatesProvider _ratesProvider,
    address _vaultERC20,
    address _vaultETH
  ) public
  {
    token = _token;
    userRegistry = _userRegistry;
    ratesProvider = _ratesProvider;
    vaultERC20 = _vaultERC20;
    vaultETH = _vaultETH;
  }

  /**
   * @dev fallback function
   */
  function () external payable {
    require(msg.data.length == 0, "TOS05");
    investETH();
  }

  /**
   * @dev returns the token sold
   */
  function token() public view returns (ERC20) {
    return token;
  }

  /**
   * @dev returns the vault used to hold ETH
   */
  function vaultETH() public view returns (address) {
    return vaultETH;
  }

  /**
   * @dev returns the vault which holds tokens
   */
  function vaultERC20() public view returns (address) {
    return vaultERC20;
  }

  function userRegistry() public view returns (IUserRegistry) {
    return userRegistry;
  }

  function ratesProvider() public view returns (IRatesProvider) {
    return ratesProvider;
  }

  function sharePurchaseAgreementHash() public view returns (bytes32) {
    return sharePurchaseAgreementHash;
  }

  /* Sale status */
  function startAt() public view returns (uint256) {
    return startAt;
  }

  function endAt() public view returns (uint256) {
    return endAt;
  }

  function raisedETH() public view returns (uint256) {
    return raisedETH;
  }

  function raisedCHF() public view returns (uint256) {
    return raisedCHF;
  }

  function totalRaisedCHF() public view returns (uint256) {
    return totalRaisedCHF;
  }

  function refundedETH() public view returns (uint256) {
    return refundedETH;
  }

  function availableSupply() public view returns (uint256) {
    uint256 vaultSupply = token.balanceOf(vaultERC20);
    uint256 allowance = token.allowance(vaultERC20, address(this));
    return (vaultSupply < allowance) ? vaultSupply : allowance;
  }
 
  /* Investor specific attributes */
  function investorUnspentETH(uint256 _investorId)
    public view returns (uint256)
  {
    return investors[_investorId].unspentETH;
  }

  function investorInvestedCHF(uint256 _investorId)
    public view returns (uint256)
  {
    return investors[_investorId].investedCHF;
  }

  function investorAcceptedSPA(uint256 _investorId)
    public view returns (bool)
  {
    return investors[_investorId].acceptedSPA;
  }

  function investorAllocations(uint256 _investorId)
    public view returns (uint256)
  {
    return investors[_investorId].allocations;
  }

  function investorTokens(uint256 _investorId) public view returns (uint256) {
    return investors[_investorId].tokens;
  }

  function investorCount() public view returns (uint256) {
    return investorCount;
  }

  /**
   * @dev minimal autowithdraw threshold
   */
  function minimalAutoWithdraw() public view returns (uint256) {
    return MINIMAL_AUTO_WITHDRAW;
  }

  /**
   * @dev minimal balance
   */
  function minimalBalance() public view returns (uint256) {
    return minimalBalance;
  }

  /**
   * @dev token base price in CHF cents
   */
  function basePriceCHFCent() public view returns (uint256) {
    return BASE_PRICE_CHF_CENT;
  }

  /**
   * @dev updateMinimalBalance
   */
  function updateMinimalBalance(uint256 _minimalBalance) public returns (uint256) {
    minimalBalance = _minimalBalance;
  }

  /* Share Purchase Agreement */
  /**
   * @dev define SPA
   */
  function defineSPA(bytes32 _sharePurchaseAgreementHash)
    public onlyOwner returns (bool)
  {
    sharePurchaseAgreementHash = _sharePurchaseAgreementHash;
    emit SalePurchaseAgreementHash(_sharePurchaseAgreementHash);
  }

  /**
   * @dev Accept SPA and invest if msg.value > 0
   */
  function acceptSPA(bytes32 _sharePurchaseAgreementHash)
    public beforeSaleIsClosed payable returns (bool)
  {
    require(
      _sharePurchaseAgreementHash == sharePurchaseAgreementHash, "TOS06");
    uint256 investorId = userRegistry.userId(msg.sender);
    require(investorId > 0, "TOS07");
    investors[investorId].acceptedSPA = true;
    investorCount++;

    if (msg.value > 0) {
      investETH();
    }
  }

  /* Investment */
  function investETH() public saleIsOpened payable {
    //Accepting SharePurchaseAgreement is temporarily offchain
    //uint256 investorId = userRegistry.userId(msg.sender);
    //require(investors[investorId].acceptedSPA, "TOS08");
    investInternal(msg.sender, msg.value, 0);
    autoWithdrawETHFunds();
  }

  /**
   * @dev add off chain investment
   */
  function addOffChainInvestment(address _investor, uint256 _amountCHF)
    public onlyAuthority
  {
    investInternal(_investor, 0, _amountCHF);
  }

  /* Schedule */ 
  /**
   * @dev update schedule
   */
  function updateSchedule(uint256 _startAt, uint256 _endAt)
    public onlyAuthority beforeSaleIsOpened
  {
    require(_startAt < _endAt, "TOS09");
    startAt = _startAt;
    endAt = _endAt;
  }

  /* Allocations admin */
  /**
   * @dev allocate
   */
  function allocateTokens(address _investor, uint256 _amount)
    public onlyAuthority beforeSaleIsClosed returns (bool)
  {
    uint256 investorId = userRegistry.userId(_investor);
    require(investorId > 0, "TOS10");
    Investor storage investor = investors[investorId];
    
    allocatedTokens = allocatedTokens.sub(investor.allocations).add(_amount);
    require(allocatedTokens <= availableSupply(), "TOS11");

    investor.allocations = _amount;
    emit Allocation(investorId, _amount);
  }

  /**
   * @dev allocate many
   */
  function allocateManyTokens(address[] _investors, uint256[] _amounts)
    public onlyAuthority beforeSaleIsClosed returns (bool)
  {
    require(_investors.length == _amounts.length, "TOS12");
    for (uint256 i = 0; i < _investors.length; i++) {
      allocateTokens(_investors[i], _amounts[i]);
    }
  }

  /* ETH administration */
  /**
   * @dev fund ETH
   */
  function fundETH() public payable onlyAuthority {
    emit FundETH(msg.value);
  }

  /**
   * @dev refund unspent ETH many
   */
  function refundManyUnspentETH(address[] _receivers) public onlyAuthority {
    for(uint256 i = 0; i < _receivers.length; i++) {
      refundUnspentETH(_receivers[i]);
    }
  }

  /**
   * @dev refund unspent ETH
   */
  function refundUnspentETH(address _receiver) public onlyAuthority {
    uint256 investorId = userRegistry.userId(_receiver);
    require(investorId != 0, "TOS13");
    Investor storage investor = investors[investorId];

    if (investor.unspentETH > 0) {
      // solium-disable-next-line security/no-send
      require(_receiver.send(investor.unspentETH), "TOS14");
      refundedETH = refundedETH.add(investor.unspentETH);
      emit WithdrawETH(_receiver, investor.unspentETH);
      investor.unspentETH = 0;
    }
  }

  /**
   * @dev withdraw ETH funds
   */
  function withdrawETHFunds() public onlyAuthority {
    uint256 balance = address(this).balance;
    if (balance > minimalBalance) {
      uint256 amount = balance.sub(minimalBalance);
      // solium-disable-next-line security/no-send
      require(vaultETH.send(amount), "TOS15");
      emit WithdrawETH(vaultETH, amount);
    }
  }

  /**
   * @dev withdraw all ETH funds
   */
  function withdrawAllETHFunds() public onlyAuthority {
    uint256 balance = address(this).balance;
    // solium-disable-next-line security/no-send
    require(vaultETH.send(balance), "TOS15");
    emit WithdrawETH(vaultETH, balance);
  }

  /**
   * @dev auto withdraw ETH funds
   */
  function autoWithdrawETHFunds() private {
    uint256 balance = address(this).balance;
    if (balance >= minimalBalance.add(MINIMAL_AUTO_WITHDRAW)) {
      uint256 amount = balance.sub(minimalBalance);
      // solium-disable-next-line security/no-send
      if (vaultETH.send(amount)) {
        emit WithdrawETH(vaultETH, amount);
      }
    }
  }

  /**
   * @dev invest internal
   */
  function investInternal(
    address _investor, uint256 _amountETH, uint256 _amountCHF)
    private
  {
    // investment with _amountETH is decentralized
    // investment with _amountCHF is centralized
    // They are mutually exclusive
    require((_amountETH != 0 && _amountCHF == 0) ||
      (_amountETH == 0 && _amountCHF != 0), "TOS16");

    require(ratesProvider.rateWEIPerCHFCent() != 0, "TOS17");
    uint256 investorId = userRegistry.userId(_investor);
    require(userRegistry.isValid(investorId), "TOS18");

    Investor storage investor = investors[investorId];

    uint256 contributionCHF = ratesProvider.convertWEIToCHFCent(
      investor.unspentETH);

    if (_amountETH > 0) {
      contributionCHF = contributionCHF.add(
        ratesProvider.convertWEIToCHFCent(_amountETH));
    }
    if (_amountCHF > 0) {
      contributionCHF = contributionCHF.add(_amountCHF);
    }

    uint256 tokens = contributionCHF.div(BASE_PRICE_CHF_CENT);
    uint256 availableTokens = availableSupply().sub(
      allocatedTokens).add(investor.allocations);
    require(availableTokens != 0, "TOS19");

    if (tokens > availableTokens) {
      tokens = availableTokens;
    }

    /** Calculating unspentETH value **/
    uint256 investedCHF = tokens.mul(BASE_PRICE_CHF_CENT);
    uint256 unspentContributionCHF = contributionCHF.sub(investedCHF);

    uint256 unspentETH = 0;
    if (unspentContributionCHF != 0) {
      if (_amountCHF > 0) {
        // Prevent CHF investment LARGER than available supply
        // from creating a too large and dangerous unspentETH value
        require(unspentContributionCHF < BASE_PRICE_CHF_CENT, "TOS20");
      }
      unspentETH = ratesProvider.convertCHFCentToWEI(
        unspentContributionCHF);
    }

    /** Spent ETH **/
    uint256 spentETH = 0;
    if (investor.unspentETH == unspentETH) {
      spentETH = _amountETH;
    } else {
      uint256 unspentETHDiff = (unspentETH > investor.unspentETH)
        ? unspentETH.sub(investor.unspentETH)
        : investor.unspentETH.sub(unspentETH);

      if (_amountCHF > 0) {
        if (unspentETH < investor.unspentETH) {
          spentETH = unspentETHDiff;
        }
        // if unspentETH > investor.unspentETH
        // then CHF has been converted into ETH
        // and no ETH were spent
      }
      if (_amountETH > 0) {
        spentETH = (unspentETH > investor.unspentETH)
          ? _amountETH.sub(unspentETHDiff)
          : _amountETH.add(unspentETHDiff);
      }
    }

    investor.unspentETH = unspentETH;
    investor.investedCHF = investor.investedCHF.add(investedCHF);
    investor.tokens = investor.tokens.add(tokens);
    raisedCHF = raisedCHF.add(_amountCHF);
    raisedETH = raisedETH.add(spentETH);
    totalRaisedCHF = totalRaisedCHF.add(investedCHF);

    allocatedTokens = allocatedTokens.sub(investor.allocations);
    investor.allocations = (investor.allocations > tokens)
      ? investor.allocations.sub(tokens) : 0;
    allocatedTokens = allocatedTokens.add(investor.allocations);
    require(
      token.transferFrom(vaultERC20, _investor, tokens),
      "TOS21");

    if (spentETH > 0) {
      emit ChangeETHCHF(
        _investor,
        spentETH,
        ratesProvider.convertWEIToCHFCent(spentETH),
        ratesProvider.rateWEIPerCHFCent());
    }
    emit Investment(investorId, investedCHF);
  }

  /* Util */
  /**
   * @dev current time
   */
  function currentTime() private view returns (uint256) {
    // solium-disable-next-line security/no-block-members
    return now;
  }
}

    Contract ABI  
[{"constant":true,"inputs":[],"name":"allocatedTokens","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_investorId","type":"uint256"}],"name":"investorTokens","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"raisedCHF","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_sharePurchaseAgreementHash","type":"bytes32"}],"name":"defineSPA","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"vaultETH","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_sharePurchaseAgreementHash","type":"bytes32"}],"name":"acceptSPA","outputs":[{"name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_receivers","type":"address[]"}],"name":"refundManyUnspentETH","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"vaultERC20","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"raisedETH","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalRaisedCHF","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"authorityAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_investorId","type":"uint256"}],"name":"investorAcceptedSPA","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ratesProvider","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"userRegistry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"withdrawETHFunds","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_investorId","type":"uint256"}],"name":"investorInvestedCHF","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_investorId","type":"uint256"}],"name":"investorAllocations","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"endAt","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"availableSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_investor","type":"address"},{"name":"_amount","type":"uint256"}],"name":"allocateTokens","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"sharePurchaseAgreementHash","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"investETH","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"minimalAutoWithdraw","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"fundETH","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"basePriceCHFCent","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_investors","type":"address[]"},{"name":"_amounts","type":"uint256[]"}],"name":"allocateManyTokens","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_receiver","type":"address"}],"name":"refundUnspentETH","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"startAt","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_investor","type":"address"},{"name":"_amountCHF","type":"uint256"}],"name":"addOffChainInvestment","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"investorCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"refundedETH","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_startAt","type":"uint256"},{"name":"_endAt","type":"uint256"}],"name":"updateSchedule","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"withdrawAllETHFunds","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":"minimalBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_investorId","type":"uint256"}],"name":"investorUnspentETH","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"token","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_address","type":"address"}],"name":"defineAuthority","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_minimalBalance","type":"uint256"}],"name":"updateMinimalBalance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_token","type":"address"},{"name":"_userRegistry","type":"address"},{"name":"_ratesProvider","type":"address"},{"name":"_vaultERC20","type":"address"},{"name":"_vaultETH","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"name","type":"string"},{"indexed":false,"name":"_address","type":"address"}],"name":"AuthorityDefined","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"},{"anonymous":false,"inputs":[{"indexed":false,"name":"sharePurchaseAgreement","type":"bytes32"}],"name":"SalePurchaseAgreementHash","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"investorId","type":"uint256"},{"indexed":false,"name":"tokens","type":"uint256"}],"name":"Allocation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"investorId","type":"uint256"},{"indexed":false,"name":"spentCHF","type":"uint256"}],"name":"Investment","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"investor","type":"address"},{"indexed":false,"name":"amount","type":"uint256"},{"indexed":false,"name":"converted","type":"uint256"},{"indexed":false,"name":"rate","type":"uint256"}],"name":"ChangeETHCHF","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"FundETH","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"receiver","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"WithdrawETH","type":"event"}]

  Contract Creation Code Switch To Opcodes View
60806040526706f05b59d3b2000060075563f48648f060095563f48648f0600a5534801561002c57600080fd5b5060405160a080613eb18339810180604052810190808051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555083600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555082600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050505050613ca1806102106000396000f3006080604052600436106101f8576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff1680622f95691461027d5780630562ac27146102a857806308510f18146102e95780630ab297e3146103145780630c8b28c31461035d5780631b24725a146103b45780631f2aa2ed146103f05780632235919b146104565780632a486a28146104ad5780632d1bc65c146104d85780633c695d4e14610503578063431f4e2e1461055a5780634ea4fbec1461059f5780635c7460d6146105f6578063629f349d1461064d578063715018a61461066457806374a85cb91461067b5780637b7f3157146106bc5780637cc3ae8c146106fd5780637ecc2b561461072857806386ce0285146107535780638da5cb5b146107b857806391c9b2c21461080f578063a39cfae614610842578063a88c41a61461084c578063a9e31ac914610877578063aaf9b32914610881578063af01ce81146108ac578063b9bb3a5a1461096d578063c7446565146109b0578063cd9d5353146109db578063d7e64c0014610a28578063d824034b14610a53578063e6671f9014610a7e578063f049191114610ab5578063f2fde38b14610acc578063f5e30ed614610b0f578063f62e33d914610b3a578063fc0c546a14610b7b578063fc21e16714610bd2578063fca9475714610c5b575b600080369050141515610273576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f544f53303500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61027b610c9c565b005b34801561028957600080fd5b50610292610d48565b6040518082815260200191505060405180910390f35b3480156102b457600080fd5b506102d360048036038101908080359060200190929190505050610d4e565b6040518082815260200191505060405180910390f35b3480156102f557600080fd5b506102fe610d6e565b6040518082815260200191505060405180910390f35b34801561032057600080fd5b506103436004803603810190808035600019169060200190929190505050610d78565b604051808215151515815260200191505060405180910390f35b34801561036957600080fd5b50610372610e24565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6103d66004803603810190808035600019169060200190929190505050610e4e565b604051808215151515815260200191505060405180910390f35b3480156103fc57600080fd5b506104546004803603810190808035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919291929050505061111e565b005b34801561046257600080fd5b5061046b611224565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156104b957600080fd5b506104c261124e565b6040518082815260200191505060405180910390f35b3480156104e457600080fd5b506104ed611258565b6040518082815260200191505060405180910390f35b34801561050f57600080fd5b50610518611262565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561056657600080fd5b506105856004803603810190808035906020019092919050505061128c565b604051808215151515815260200191505060405180910390f35b3480156105ab57600080fd5b506105b46112b9565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561060257600080fd5b5061060b6112e3565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561065957600080fd5b5061066261130d565b005b34801561067057600080fd5b5061067961156d565b005b34801561068757600080fd5b506106a66004803603810190808035906020019092919050505061166f565b6040518082815260200191505060405180910390f35b3480156106c857600080fd5b506106e76004803603810190808035906020019092919050505061168f565b6040518082815260200191505060405180910390f35b34801561070957600080fd5b506107126116af565b6040518082815260200191505060405180910390f35b34801561073457600080fd5b5061073d6116b9565b6040518082815260200191505060405180910390f35b34801561075f57600080fd5b5061079e600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611940565b604051808215151515815260200191505060405180910390f35b3480156107c457600080fd5b506107cd611d14565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561081b57600080fd5b50610824611d39565b60405180826000191660001916815260200191505060405180910390f35b61084a610c9c565b005b34801561085857600080fd5b50610861611d43565b6040518082815260200191505060405180910390f35b61087f611d53565b005b34801561088d57600080fd5b50610896611e51565b6040518082815260200191505060405180910390f35b3480156108b857600080fd5b506109536004803603810190808035906020019082018035906020019080806020026020016040519081016040528093929190818152602001838360200280828437820191505050505050919291929080359060200190820180359060200190808060200260200160405190810160405280939291908181526020018383602002808284378201915050505050509192919290505050611e5b565b604051808215151515815260200191505060405180910390f35b34801561097957600080fd5b506109ae600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612078565b005b3480156109bc57600080fd5b506109c5612420565b6040518082815260200191505060405180910390f35b3480156109e757600080fd5b50610a26600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061242a565b005b348015610a3457600080fd5b50610a3d6124ff565b6040518082815260200191505060405180910390f35b348015610a5f57600080fd5b50610a68612509565b6040518082815260200191505060405180910390f35b348015610a8a57600080fd5b50610ab36004803603810190808035906020019092919080359060200190929190505050612513565b005b348015610ac157600080fd5b50610aca6126e1565b005b348015610ad857600080fd5b50610b0d600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061291d565b005b348015610b1b57600080fd5b50610b24612984565b6040518082815260200191505060405180910390f35b348015610b4657600080fd5b50610b656004803603810190808035906020019092919050505061298e565b6040518082815260200191505060405180910390f35b348015610b8757600080fd5b50610b906129ae565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610bde57600080fd5b50610c59600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506129d8565b005b348015610c6757600080fd5b50610c8660048036038101908080359060200190929190505050612b48565b6040518082815260200191505060405180910390f35b600954610ca7612b56565b10158015610cbe5750600a54610cbb612b56565b11155b1515610d32576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f544f53303200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b610d3e33346000612b5e565b610d466139b0565b565b600f5481565b600060106000838152602001908152602001600020600401549050919050565b6000600c54905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515610dd557600080fd5b81600881600019169055507f17e73384223b513b8527d30845d17eb190bb29269f323c3bac7f57bcb88635958260405180826000191660001916815260200191505060405180910390a1919050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600080600a54610e5c612b56565b11151515610ed2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f544f53303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600854600019168360001916141515610f53576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f544f53303600000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663376fe102336040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801561101057600080fd5b505af1158015611024573d6000803e3d6000fd5b505050506040513d602081101561103a57600080fd5b810190808051906020019092919050505090506000811115156110c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f544f53303700000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60016010600083815260200190815260200160002060020160006101000a81548160ff021916908315150217905550601160008154809291906001019190505550600034111561111857611117610c9c565b5b50919050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156111e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f415530310000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600090505b815181101561122057611213828281518110151561120457fe5b90602001906020020151612078565b80806001019150506111ea565b5050565b6000600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600b54905090565b6000600d54905090565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60006010600083815260200190815260200160002060020160009054906101000a900460ff169050919050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156113d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f415530310000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff163191506007548211156115695761140e60075483613af890919063ffffffff16565b9050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015156114db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f544f53313500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b7f566e45b1c8057e725bf62796a7f1d37ae294393cab069725a09daddd1af98b79600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15b5050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156115c857600080fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482060405160405180910390a260008060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b600060106000838152602001908152602001600020600101549050919050565b600060106000838152602001908152602001600020600301549050919050565b6000600a54905090565b6000806000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b15801561179d57600080fd5b505af11580156117b1573d6000803e3d6000fd5b505050506040513d60208110156117c757600080fd5b81019080805190602001909291905050509150600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16306040518363ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200192505050602060405180830381600087803b1580156118ed57600080fd5b505af1158015611901573d6000803e3d6000fd5b505050506040513d602081101561191757600080fd5b810190808051906020019092919050505090508082106119375780611939565b815b9250505090565b6000806000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611a0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f415530310000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600a54611a15612b56565b11151515611a8b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f544f53303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663376fe102866040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015611b4857600080fd5b505af1158015611b5c573d6000803e3d6000fd5b505050506040513d6020811015611b7257600080fd5b81019080805190602001909291905050509150600082111515611bfd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f544f53313000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b601060008381526020019081526020016000209050611c3d84611c2f8360030154600f54613af890919063ffffffff16565b613b1190919063ffffffff16565b600f81905550611c4b6116b9565b600f5411151515611cc4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f544f53313100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8381600301819055507f2ccf21bc8a43b499670fe41c33ca0f7b56c83863aca7c1494f0ede9068d2731a8285604051808381526020018281526020019250505060405180910390a1505092915050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600854905090565b60006706f05b59d3b20000905090565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611e18576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f415530310000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b7ffb52132c41e08fba4ca49ec0ecc612f9e9e65735297a70f7105f545d9448cd75346040518082815260200191505060405180910390a1565b60006101f4905090565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515611f23576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f415530310000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600a54611f2e612b56565b11151515611fa4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f544f53303300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8251845114151561201d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f544f53313200000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600090505b835181101561207157612063848281518110151561203c57fe5b90602001906020020151848381518110151561205457fe5b90602001906020020151611940565b508080600101915050612022565b5092915050565b600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612140576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f415530310000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663376fe102846040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b1580156121fd57600080fd5b505af1158015612211573d6000803e3d6000fd5b505050506040513d602081101561222757600080fd5b81019080805190602001909291905050509150600082141515156122b3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f544f53313300000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b60106000838152602001908152602001600020905060008160000154111561241b578273ffffffffffffffffffffffffffffffffffffffff166108fc82600001549081150290604051600060405180830381858888f193505050501515612382576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f544f53313400000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b61239b8160000154600e54613b1190919063ffffffff16565b600e819055507f566e45b1c8057e725bf62796a7f1d37ae294393cab069725a09daddd1af98b79838260000154604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a1600081600001819055505b505050565b6000600954905090565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156124ef576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f415530310000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6124fb82600083612b5e565b5050565b6000601154905090565b6000600e54905090565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156125d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f415530310000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6009546125e3612b56565b101515612658576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f544f53303100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b80821015156126cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f544f53303900000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8160098190555080600a819055505050565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415156127a8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260048152602001807f415530310000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b3073ffffffffffffffffffffffffffffffffffffffff16319050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050151561288d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f544f53313500000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b7f566e45b1c8057e725bf62796a7f1d37ae294393cab069725a09daddd1af98b79600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a150565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614151561297857600080fd5b61298181613b2d565b50565b6000600754905090565b600060106000838152602001908152602001600020600001549050919050565b6000600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141515612a3357600080fd5b7fc8c81ac5a1b95ead7b5f71eafa51c9a1436e443c27ba33460885b9debe345abf828260405180806020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828103825284818151815260200191508051906020019080838360005b83811015612ac8578082015181840152602081019050612aad565b50505050905090810190601f168015612af55780820380516001836020036101000a031916815260200191505b50935050505060405180910390a180600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b600081600781905550919050565b600042905090565b60008060008060008060008060008060008c14158015612b7e575060008b145b80612b96575060008c148015612b95575060008b14155b5b1515612c0a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f544f53313600000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630ac37bd66040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b158015612c9257600080fd5b505af1158015612ca6573d6000803e3d6000fd5b505050506040513d6020811015612cbc57600080fd5b810190808051906020019092919050505014151515612d43576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f544f53313700000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663376fe1028e6040518263ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050602060405180830381600087803b158015612e0057600080fd5b505af1158015612e14573d6000803e3d6000fd5b505050506040513d6020811015612e2a57600080fd5b81019080805190602001909291905050509950600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663f577a5008b6040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b158015612ece57600080fd5b505af1158015612ee2573d6000803e3d6000fd5b505050506040513d6020811015612ef857600080fd5b81019080805190602001909291905050501515612f7d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f544f53313800000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b601060008b81526020019081526020016000209850600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a3b1f60f8a600001546040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b15801561302757600080fd5b505af115801561303b573d6000803e3d6000fd5b505050506040513d602081101561305157600080fd5b8101908080519060200190929190505050975060008c111561314e5761314b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a3b1f60f8e6040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b15801561310157600080fd5b505af1158015613115573d6000803e3d6000fd5b505050506040513d602081101561312b57600080fd5b810190808051906020019092919050505089613b1190919063ffffffff16565b97505b60008b111561316d5761316a8b89613b1190919063ffffffff16565b97505b6131826101f489613c2790919063ffffffff16565b96506131b689600301546131a8600f5461319a6116b9565b613af890919063ffffffff16565b613b1190919063ffffffff16565b955060008614151515613231576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f544f53313900000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b8587111561323d578596505b6132526101f488613c3d90919063ffffffff16565b94506132678589613af890919063ffffffff16565b9350600092506000841415156133c95760008b11156132fa576101f4841015156132f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f544f53323000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5b600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663dc7b0ae6856040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b15801561338b57600080fd5b505af115801561339f573d6000803e3d6000fd5b505050506040513d60208110156133b557600080fd5b810190808051906020019092919050505092505b6000915082896000015414156133e1578b9150613480565b8860000154831161340857613403838a60000154613af890919063ffffffff16565b613420565b61341f896000015484613af890919063ffffffff16565b5b905060008b111561343c57886000015483101561343b578091505b5b60008c111561347f578860000154831161346857613463818d613b1190919063ffffffff16565b61347c565b61347b818d613af890919063ffffffff16565b5b91505b5b8289600001819055506134a0858a60010154613b1190919063ffffffff16565b89600101819055506134bf878a60040154613b1190919063ffffffff16565b89600401819055506134dc8b600c54613b1190919063ffffffff16565b600c819055506134f782600b54613b1190919063ffffffff16565b600b8190555061351285600d54613b1190919063ffffffff16565b600d819055506135318960030154600f54613af890919063ffffffff16565b600f8190555086896003015411613549576000613561565b613560878a60030154613af890919063ffffffff16565b5b89600301819055506135828960030154600f54613b1190919063ffffffff16565b600f81905550600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168f8a6040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b1580156136a357600080fd5b505af11580156136b7573d6000803e3d6000fd5b505050506040513d60208110156136cd57600080fd5b81019080805190602001909291905050501515613752576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260058152602001807f544f53323100000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000821115613962577fdeaa92aa373191aee90a177118df53483d5f83ba9f14e5aef4ebb53fef1af76e8d83600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a3b1f60f866040518263ffffffff167c010000000000000000000000000000000000000000000000000000000002815260040180828152602001915050602060405180830381600087803b15801561380f57600080fd5b505af1158015613823573d6000803e3d6000fd5b505050506040513d602081101561383957600080fd5b8101908080519060200190929190505050600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16630ac37bd66040518163ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401602060405180830381600087803b1580156138d057600080fd5b505af11580156138e4573d6000803e3d6000fd5b505050506040513d60208110156138fa57600080fd5b8101908080519060200190929190505050604051808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200182815260200194505050505060405180910390a15b7f85369d2981b3997d58407719c231e73f6aa20ff0098b02824bc36d0bf81b0b3b8a86604051808381526020018281526020019250505060405180910390a150505050505050505050505050565b6000803073ffffffffffffffffffffffffffffffffffffffff163191506139ea6706f05b59d3b20000600754613b1190919063ffffffff16565b82101515613af457613a0760075483613af890919063ffffffff16565b9050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f1935050505015613af3577f566e45b1c8057e725bf62796a7f1d37ae294393cab069725a09daddd1af98b79600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019250505060405180910390a15b5b5050565b6000828211151515613b0657fe5b818303905092915050565b60008183019050828110151515613b2457fe5b80905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515613b6957600080fd5b8073ffffffffffffffffffffffffffffffffffffffff166000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008183811515613c3457fe5b04905092915050565b600080831415613c505760009050613c6f565b8183029050818382811515613c6157fe5b04141515613c6b57fe5b8090505b929150505600a165627a7a723058206816163681dcf8c8114ccacfff2b3ad5134da26e99d63e48e1751aa3e20c7e68002900000000000000000000000096c645d3d3706f793ef52c19bbace441900ed47d0000000000000000000000004e19d015b2b4ff6c0aefc078c9ae1c079bb6a64a00000000000000000000000065d30deca4f8bca6ad637df2804213722859063000000000000000000000000009519a92007e055c8a727df194cd951da654b61600000000000000000000000074e6acf300e8c8d8ef7c1f85d2589fc1fcc8a500

    Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000096c645d3d3706f793ef52c19bbace441900ed47d0000000000000000000000004e19d015b2b4ff6c0aefc078c9ae1c079bb6a64a00000000000000000000000065d30deca4f8bca6ad637df2804213722859063000000000000000000000000009519a92007e055c8a727df194cd951da654b61600000000000000000000000074e6acf300e8c8d8ef7c1f85d2589fc1fcc8a500

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 00000000000000000000000096c645d3d3706f793ef52c19bbace441900ed47d
Arg [1] : 0000000000000000000000004e19d015b2b4ff6c0aefc078c9ae1c079bb6a64a
Arg [2] : 00000000000000000000000065d30deca4f8bca6ad637df28042137228590630
Arg [3] : 00000000000000000000000009519a92007e055c8a727df194cd951da654b616
Arg [4] : 00000000000000000000000074e6acf300e8c8d8ef7c1f85d2589fc1fcc8a500


   Swarm Source:
bzzr://6816163681dcf8c8114ccacfff2b3ad5134da26e99d63e48e1751aa3e20c7e68

 

View All
Block Age transaction Difficulty GasUsed Reward
View All
Block Age UncleNumber Difficulty GasUsed Reward
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.