ETH Price: $3,197.06 (-1.61%)
Gas: 41 Gwei

Token

Cardstack (CARD)
 

Overview

Max Total Supply

6,000,000,000 CARD

Holders

6,348 (0.00%)

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

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

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

Contract Source Code Verified (Exact Match)

Contract Name:
CardStackToken

Compiler Version
v0.4.24+commit.e67f0147

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

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

pragma solidity ^0.4.13;

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;
  }
}

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;
  }
}

interface ITokenLedger {
  function totalTokens() external view returns (uint256);
  function totalInCirculation() external view returns (uint256);
  function balanceOf(address account) external view returns (uint256);
  function mintTokens(uint256 amount) external;
  function transfer(address sender, address reciever, uint256 amount) external;
  function creditAccount(address account, uint256 amount) external;
  function debitAccount(address account, uint256 amount) external;
  function addAdmin(address admin) external;
  function removeAdmin(address admin) external;
}

library CstLibrary {
  using SafeMath for uint256;

  function getTokenName(address _storage) public view returns(bytes32) {
    return ExternalStorage(_storage).getBytes32Value("cstTokenName");
  }

  function setTokenName(address _storage, bytes32 tokenName) public {
    ExternalStorage(_storage).setBytes32Value("cstTokenName", tokenName);
  }

  function getTokenSymbol(address _storage) public view returns(bytes32) {
    return ExternalStorage(_storage).getBytes32Value("cstTokenSymbol");
  }

  function setTokenSymbol(address _storage, bytes32 tokenName) public {
    ExternalStorage(_storage).setBytes32Value("cstTokenSymbol", tokenName);
  }

  function getBuyPrice(address _storage) public view returns(uint256) {
    return ExternalStorage(_storage).getUIntValue("cstBuyPrice");
  }

  function setBuyPrice(address _storage, uint256 value) public {
    ExternalStorage(_storage).setUIntValue("cstBuyPrice", value);
  }

  function getCirculationCap(address _storage) public view returns(uint256) {
    return ExternalStorage(_storage).getUIntValue("cstCirculationCap");
  }

  function setCirculationCap(address _storage, uint256 value) public {
    ExternalStorage(_storage).setUIntValue("cstCirculationCap", value);
  }

  function getBalanceLimit(address _storage) public view returns(uint256) {
    return ExternalStorage(_storage).getUIntValue("cstBalanceLimit");
  }

  function setBalanceLimit(address _storage, uint256 value) public {
    ExternalStorage(_storage).setUIntValue("cstBalanceLimit", value);
  }

  function getFoundation(address _storage) public view returns(address) {
    return ExternalStorage(_storage).getAddressValue("cstFoundation");
  }

  function setFoundation(address _storage, address value) public {
    ExternalStorage(_storage).setAddressValue("cstFoundation", value);
  }

  function getAllowance(address _storage, address account, address spender) public view returns (uint256) {
    return ExternalStorage(_storage).getMultiLedgerValue("cstAllowance", account, spender);
  }

  function setAllowance(address _storage, address account, address spender, uint256 allowance) public {
    ExternalStorage(_storage).setMultiLedgerValue("cstAllowance", account, spender, allowance);
  }

  function getCustomBuyerLimit(address _storage, address buyer) public view returns (uint256) {
    return ExternalStorage(_storage).getLedgerValue("cstCustomBuyerLimit", buyer);
  }

  function setCustomBuyerLimit(address _storage, address buyer, uint256 value) public {
    ExternalStorage(_storage).setLedgerValue("cstCustomBuyerLimit", buyer, value);
  }

  function getCustomBuyerForIndex(address _storage, uint256 index) public view returns (address) {
    return ExternalStorage(_storage).ledgerEntryForIndex(keccak256("cstCustomBuyerLimit"), index);
  }

  function getCustomBuyerMappingCount(address _storage) public view returns(uint256) {
    return ExternalStorage(_storage).getLedgerCount("cstCustomBuyerLimit");
  }

  function getApprovedBuyer(address _storage, address buyer) public view returns (bool) {
    return ExternalStorage(_storage).getBooleanMapValue("cstApprovedBuyer", buyer);
  }

  function setApprovedBuyer(address _storage, address buyer, bool value) public {
    ExternalStorage(_storage).setBooleanMapValue("cstApprovedBuyer", buyer, value);
  }

  function getApprovedBuyerForIndex(address _storage, uint256 index) public view returns (address) {
    return ExternalStorage(_storage).booleanMapEntryForIndex(keccak256("cstApprovedBuyer"), index);
  }

  function getApprovedBuyerMappingCount(address _storage) public view returns(uint256) {
    return ExternalStorage(_storage).getBooleanMapCount("cstApprovedBuyer");
  }

  function getTotalUnvestedAndUnreleasedTokens(address _storage) public view returns(uint256) {
    return ExternalStorage(_storage).getUIntValue("cstUnvestedAndUnreleasedTokens");
  }

  function setTotalUnvestedAndUnreleasedTokens(address _storage, uint256 value) public {
    ExternalStorage(_storage).setUIntValue("cstUnvestedAndUnreleasedTokens", value);
  }

  function vestingMappingSize(address _storage) public view returns(uint256) {
    return ExternalStorage(_storage).getLedgerCount("cstFullyVestedAmount");
  }

  function vestingBeneficiaryForIndex(address _storage, uint256 index) public view returns(address) {
    return ExternalStorage(_storage).ledgerEntryForIndex(keccak256("cstFullyVestedAmount"), index);
  }

  function releasableAmount(address _storage, address beneficiary) public view returns (uint256) {
    uint256 releasedAmount = getVestingReleasedAmount(_storage, beneficiary);
    return vestedAvailableAmount(_storage, beneficiary).sub(releasedAmount);
  }

  function vestedAvailableAmount(address _storage, address beneficiary) public view returns (uint256) {
    uint256 start = getVestingStart(_storage, beneficiary);
    uint256 fullyVestedAmount = getFullyVestedAmount(_storage, beneficiary);

    if (start == 0 || fullyVestedAmount == 0) {
      return 0;
    }

    uint256 duration = getVestingDuration(_storage, beneficiary);
    if (duration == 0) {
      return 0;
    }
    uint256 cliff = getVestingCliff(_storage, beneficiary);
    uint256 revokeDate = getVestingRevokeDate(_storage, beneficiary);

    if (now < cliff || (revokeDate > 0 && revokeDate < cliff)) {
      return 0;
    } else if (revokeDate > 0 && revokeDate > cliff) {
      return fullyVestedAmount.mul(revokeDate.sub(start)).div(duration);
    } else if (now >= start.add(duration)) {
      return fullyVestedAmount;
    } else {
      return fullyVestedAmount.mul(now.sub(start)).div(duration);
    }
  }

  function vestedAmount(address _storage, address beneficiary) public view returns (uint256) {
    uint256 start = getVestingStart(_storage, beneficiary);
    uint256 fullyVestedAmount = getFullyVestedAmount(_storage, beneficiary);

    if (start == 0 || fullyVestedAmount == 0) {
      return 0;
    }

    uint256 duration = getVestingDuration(_storage, beneficiary);
    if (duration == 0) {
      return 0;
    }

    uint256 revokeDate = getVestingRevokeDate(_storage, beneficiary);

    if (now <= start) {
      return 0;
    } else if (revokeDate > 0) {
      return fullyVestedAmount.mul(revokeDate.sub(start)).div(duration);
    } else if (now >= start.add(duration)) {
      return fullyVestedAmount;
    } else {
      return fullyVestedAmount.mul(now.sub(start)).div(duration);
    }
  }

  function canGrantVestedTokens(address _storage, address beneficiary) public view returns (bool) {
    uint256 existingFullyVestedAmount = getFullyVestedAmount(_storage, beneficiary);
    if (existingFullyVestedAmount == 0) {
      return true;
    }

    uint256 existingVestedAmount = vestedAvailableAmount(_storage, beneficiary);
    uint256 existingReleasedAmount = getVestingReleasedAmount(_storage, beneficiary);
    uint256 revokeDate = getVestingRevokeDate(_storage, beneficiary);

    if (revokeDate > 0 ||
        (existingVestedAmount == existingFullyVestedAmount &&
        existingReleasedAmount == existingFullyVestedAmount)) {
      return true;
    }

    return false;
  }

  function canRevokeVesting(address _storage, address beneficiary) public view returns (bool) {
    bool isRevocable = getVestingRevocable(_storage, beneficiary);
    uint256 revokeDate = getVestingRevokeDate(_storage, beneficiary);
    uint256 start = getVestingStart(_storage, beneficiary);
    uint256 duration = getVestingDuration(_storage, beneficiary);

    return start > 0 &&
           isRevocable &&
           revokeDate == 0 &&
           now < start.add(duration);
  }

  function revokeVesting(address _storage, address beneficiary) public {
    require(canRevokeVesting(_storage, beneficiary));

    uint256 totalUnvestedAndUnreleasedAmount = getTotalUnvestedAndUnreleasedTokens(_storage);
    uint256 unvestedAmount = getFullyVestedAmount(_storage, beneficiary).sub(vestedAvailableAmount(_storage, beneficiary));

    setVestingRevokeDate(_storage, beneficiary, now);
    setTotalUnvestedAndUnreleasedTokens(_storage, totalUnvestedAndUnreleasedAmount.sub(unvestedAmount));
  }

  function getVestingSchedule(address _storage, address _beneficiary) public
                                                                      view returns (uint256 startDate,
                                                                                        uint256 cliffDate,
                                                                                        uint256 durationSec,
                                                                                        uint256 fullyVestedAmount,
                                                                                        uint256 releasedAmount,
                                                                                        uint256 revokeDate,
                                                                                        bool isRevocable) {
    startDate         = getVestingStart(_storage, _beneficiary);
    cliffDate         = getVestingCliff(_storage, _beneficiary);
    durationSec       = getVestingDuration(_storage, _beneficiary);
    fullyVestedAmount = getFullyVestedAmount(_storage, _beneficiary);
    releasedAmount    = getVestingReleasedAmount(_storage, _beneficiary);
    revokeDate        = getVestingRevokeDate(_storage, _beneficiary);
    isRevocable       = getVestingRevocable(_storage, _beneficiary);
  }

  function setVestingSchedule(address _storage,
                              address beneficiary,
                              uint256 fullyVestedAmount,
                              uint256 startDate,
                              uint256 cliffDate,
                              uint256 duration,
                              bool isRevocable) public {
    require(canGrantVestedTokens(_storage, beneficiary));

    uint256 totalUnvestedAndUnreleasedAmount = getTotalUnvestedAndUnreleasedTokens(_storage);
    setTotalUnvestedAndUnreleasedTokens(_storage, totalUnvestedAndUnreleasedAmount.add(fullyVestedAmount));

    ExternalStorage(_storage).setLedgerValue("cstVestingStart", beneficiary, startDate);
    ExternalStorage(_storage).setLedgerValue("cstVestingCliff", beneficiary, cliffDate);
    ExternalStorage(_storage).setLedgerValue("cstVestingDuration", beneficiary, duration);
    ExternalStorage(_storage).setLedgerValue("cstFullyVestedAmount", beneficiary, fullyVestedAmount);
    ExternalStorage(_storage).setBooleanMapValue("cstVestingRevocable", beneficiary, isRevocable);

    setVestingRevokeDate(_storage, beneficiary, 0);
    setVestingReleasedAmount(_storage, beneficiary, 0);
  }

  function releaseVestedTokens(address _storage, address beneficiary) public {
    uint256 unreleased = releasableAmount(_storage, beneficiary);
    uint256 releasedAmount = getVestingReleasedAmount(_storage, beneficiary);
    uint256 totalUnvestedAndUnreleasedAmount = getTotalUnvestedAndUnreleasedTokens(_storage);

    releasedAmount = releasedAmount.add(unreleased);
    setVestingReleasedAmount(_storage, beneficiary, releasedAmount);
    setTotalUnvestedAndUnreleasedTokens(_storage, totalUnvestedAndUnreleasedAmount.sub(unreleased));
  }

  function getVestingStart(address _storage, address beneficiary) public view returns(uint256) {
    return ExternalStorage(_storage).getLedgerValue("cstVestingStart", beneficiary);
  }

  function getVestingCliff(address _storage, address beneficiary) public view returns(uint256) {
    return ExternalStorage(_storage).getLedgerValue("cstVestingCliff", beneficiary);
  }

  function getVestingDuration(address _storage, address beneficiary) public view returns(uint256) {
    return ExternalStorage(_storage).getLedgerValue("cstVestingDuration", beneficiary);
  }

  function getFullyVestedAmount(address _storage, address beneficiary) public view returns(uint256) {
    return ExternalStorage(_storage).getLedgerValue("cstFullyVestedAmount", beneficiary);
  }

  function getVestingRevocable(address _storage, address beneficiary) public view returns(bool) {
    return ExternalStorage(_storage).getBooleanMapValue("cstVestingRevocable", beneficiary);
  }

  function setVestingReleasedAmount(address _storage, address beneficiary, uint256 value) public {
    ExternalStorage(_storage).setLedgerValue("cstVestingReleasedAmount", beneficiary, value);
  }

  function getVestingReleasedAmount(address _storage, address beneficiary) public view returns(uint256) {
    return ExternalStorage(_storage).getLedgerValue("cstVestingReleasedAmount", beneficiary);
  }

  function setVestingRevokeDate(address _storage, address beneficiary, uint256 value) public {
    ExternalStorage(_storage).setLedgerValue("cstVestingRevokeDate", beneficiary, value);
  }

  function getVestingRevokeDate(address _storage, address beneficiary) public view returns(uint256) {
    return ExternalStorage(_storage).getLedgerValue("cstVestingRevokeDate", beneficiary);
  }

  function getRewardsContractHash(address _storage) public view returns (bytes32) {
    return ExternalStorage(_storage).getBytes32Value("cstRewardsContractHash");
  }

  function setRewardsContractHash(address _storage, bytes32 rewardsContractHash) public {
    ExternalStorage(_storage).setBytes32Value("cstRewardsContractHash", rewardsContractHash);
  }

}

contract ERC20 {
  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);
  function totalSupply() public view returns (uint256);
  function balanceOf(address account) public view returns (uint256);
  function transfer(address to, uint256 value) public returns (bool);
  event Transfer(address indexed _from, address indexed _to, uint256 _value);
  event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}

contract administratable is Ownable {
  using SafeMath for uint256;

  address[] public adminsForIndex;
  address[] public superAdminsForIndex;
  mapping (address => bool) public admins;
  mapping (address => bool) public superAdmins;
  mapping (address => bool) private processedAdmin;
  mapping (address => bool) private processedSuperAdmin;

  event AddAdmin(address indexed admin);
  event RemoveAdmin(address indexed admin);
  event AddSuperAdmin(address indexed admin);
  event RemoveSuperAdmin(address indexed admin);

  modifier onlyAdmins {
    if (msg.sender != owner && !superAdmins[msg.sender] && !admins[msg.sender]) revert();
    _;
  }

  modifier onlySuperAdmins {
    if (msg.sender != owner && !superAdmins[msg.sender]) revert();
    _;
  }

  function totalSuperAdminsMapping() public view returns (uint256) {
    return superAdminsForIndex.length;
  }

  function addSuperAdmin(address admin) public onlySuperAdmins {
    require(admin != address(0));
    superAdmins[admin] = true;
    if (!processedSuperAdmin[admin]) {
      superAdminsForIndex.push(admin);
      processedSuperAdmin[admin] = true;
    }

    emit AddSuperAdmin(admin);
  }

  function removeSuperAdmin(address admin) public onlySuperAdmins {
    require(admin != address(0));
    superAdmins[admin] = false;

    emit RemoveSuperAdmin(admin);
  }

  function totalAdminsMapping() public view returns (uint256) {
    return adminsForIndex.length;
  }

  function addAdmin(address admin) public onlySuperAdmins {
    require(admin != address(0));
    admins[admin] = true;
    if (!processedAdmin[admin]) {
      adminsForIndex.push(admin);
      processedAdmin[admin] = true;
    }

    emit AddAdmin(admin);
  }

  function removeAdmin(address admin) public onlySuperAdmins {
    require(admin != address(0));
    admins[admin] = false;

    emit RemoveAdmin(admin);
  }
}

contract CstLedger is ITokenLedger, administratable {

  using SafeMath for uint256;

  uint256 private _totalInCirculation; // warning this does not take into account unvested nor vested-unreleased tokens into consideration
  uint256 private _totalTokens;
  mapping (address => uint256) private _balanceOf;
  mapping (address => bool) private accounts;
  address[] public accountForIndex;

  function totalTokens() external view returns (uint256) {
    return _totalTokens;
  }

  function totalInCirculation() external view returns (uint256) {
    return _totalInCirculation;
  }

  function balanceOf(address account) external view returns (uint256) {
    return _balanceOf[account];
  }

  function mintTokens(uint256 amount) external onlyAdmins {
    _totalTokens = _totalTokens.add(amount);
  }

  function ledgerCount() external view returns (uint256) {
    return accountForIndex.length;
  }

  function makeAccountIterable(address account) internal {
    if (!accounts[account]) {
      accountForIndex.push(account);
      accounts[account] = true;
    }
  }

  function transfer(address sender, address recipient, uint256 amount) external onlyAdmins {
    require(sender != address(0));
    require(recipient != address(0));
    require(_balanceOf[sender] >= amount);

    _balanceOf[sender] = _balanceOf[sender].sub(amount);
    _balanceOf[recipient] = _balanceOf[recipient].add(amount);
    makeAccountIterable(recipient);
  }

  function creditAccount(address account, uint256 amount) external onlyAdmins { // remove tokens
    require(account != address(0));
    require(_balanceOf[account] >= amount);

    _totalInCirculation = _totalInCirculation.sub(amount);
    _balanceOf[account] = _balanceOf[account].sub(amount);
  }

  function debitAccount(address account, uint256 amount) external onlyAdmins { // add tokens
    require(account != address(0));
    _totalInCirculation = _totalInCirculation.add(amount);
    _balanceOf[account] = _balanceOf[account].add(amount);
    makeAccountIterable(account);
  }
}

contract ExternalStorage is administratable {
  using SafeMath for uint256;

  mapping(bytes32 => address[]) public primaryLedgerEntryForIndex;
  mapping(bytes32 => mapping(address => address[])) public secondaryLedgerEntryForIndex;
  mapping(bytes32 => mapping(address => mapping(address => uint256))) private MultiLedgerStorage;
  mapping(bytes32 => mapping(address => bool)) private ledgerPrimaryEntries;
  mapping(bytes32 => mapping(address => mapping(address => bool))) private ledgerSecondaryEntries;

  function getMultiLedgerValue(string record, address primaryAddress, address secondaryAddress) external view returns (uint256) {
    return MultiLedgerStorage[keccak256(abi.encodePacked(record))][primaryAddress][secondaryAddress];
  }

  function primaryLedgerCount(string record) external view returns (uint256) {
    return primaryLedgerEntryForIndex[keccak256(abi.encodePacked(record))].length;
  }

  function secondaryLedgerCount(string record, address primaryAddress) external view returns (uint256) {
    return secondaryLedgerEntryForIndex[keccak256(abi.encodePacked(record))][primaryAddress].length;
  }

  function setMultiLedgerValue(string record, address primaryAddress, address secondaryAddress, uint256 value) external onlyAdmins {
    bytes32 hash = keccak256(abi.encodePacked(record));
    if (!ledgerSecondaryEntries[hash][primaryAddress][secondaryAddress]) {
      secondaryLedgerEntryForIndex[hash][primaryAddress].push(secondaryAddress);
      ledgerSecondaryEntries[hash][primaryAddress][secondaryAddress] = true;

      if (!ledgerPrimaryEntries[hash][primaryAddress]) {
        primaryLedgerEntryForIndex[hash].push(primaryAddress);
        ledgerPrimaryEntries[hash][primaryAddress] = true;
      }
    }

    MultiLedgerStorage[hash][primaryAddress][secondaryAddress] = value;
  }

  mapping(bytes32 => address[]) public ledgerEntryForIndex;
  mapping(bytes32 => mapping(address => uint256)) private LedgerStorage;
  mapping(bytes32 => mapping(address => bool)) private ledgerAccounts;

  function getLedgerValue(string record, address _address) external view returns (uint256) {
    return LedgerStorage[keccak256(abi.encodePacked(record))][_address];
  }

  function getLedgerCount(string record) external view returns (uint256) {
    return ledgerEntryForIndex[keccak256(abi.encodePacked(record))].length;
  }

  function setLedgerValue(string record, address _address, uint256 value) external onlyAdmins {
    bytes32 hash = keccak256(abi.encodePacked(record));
    if (!ledgerAccounts[hash][_address]) {
      ledgerEntryForIndex[hash].push(_address);
      ledgerAccounts[hash][_address] = true;
    }

    LedgerStorage[hash][_address] = value;
  }

  mapping(bytes32 => address[]) public booleanMapEntryForIndex;
  mapping(bytes32 => mapping(address => bool)) private BooleanMapStorage;
  mapping(bytes32 => mapping(address => bool)) private booleanMapAccounts;

  function getBooleanMapValue(string record, address _address) external view returns (bool) {
    return BooleanMapStorage[keccak256(abi.encodePacked(record))][_address];
  }

  function getBooleanMapCount(string record) external view returns (uint256) {
    return booleanMapEntryForIndex[keccak256(abi.encodePacked(record))].length;
  }

  function setBooleanMapValue(string record, address _address, bool value) external onlyAdmins {
    bytes32 hash = keccak256(abi.encodePacked(record));
    if (!booleanMapAccounts[hash][_address]) {
      booleanMapEntryForIndex[hash].push(_address);
      booleanMapAccounts[hash][_address] = true;
    }

    BooleanMapStorage[hash][_address] = value;
  }

  mapping(bytes32 => uint256) private UIntStorage;

  function getUIntValue(string record) external view returns (uint256) {
    return UIntStorage[keccak256(abi.encodePacked(record))];
  }

  function setUIntValue(string record, uint256 value) external onlyAdmins {
    UIntStorage[keccak256(abi.encodePacked(record))] = value;
  }

  mapping(bytes32 => bytes32) private Bytes32Storage;

  function getBytes32Value(string record) external view returns (bytes32) {
    return Bytes32Storage[keccak256(abi.encodePacked(record))];
  }

  function setBytes32Value(string record, bytes32 value) external onlyAdmins {
    Bytes32Storage[keccak256(abi.encodePacked(record))] = value;
  }

  mapping(bytes32 => address) private AddressStorage;

  function getAddressValue(string record) external view returns (address) {
    return AddressStorage[keccak256(abi.encodePacked(record))];
  }

  function setAddressValue(string record, address value) external onlyAdmins {
    AddressStorage[keccak256(abi.encodePacked(record))] = value;
  }

  mapping(bytes32 => bytes) private BytesStorage;

  function getBytesValue(string record) external view returns (bytes) {
    return BytesStorage[keccak256(abi.encodePacked(record))];
  }

  function setBytesValue(string record, bytes value) external onlyAdmins {
    BytesStorage[keccak256(abi.encodePacked(record))] = value;
  }

  mapping(bytes32 => bool) private BooleanStorage;

  function getBooleanValue(string record) external view returns (bool) {
    return BooleanStorage[keccak256(abi.encodePacked(record))];
  }

  function setBooleanValue(string record, bool value) external onlyAdmins {
    BooleanStorage[keccak256(abi.encodePacked(record))] = value;
  }

  mapping(bytes32 => int256) private IntStorage;

  function getIntValue(string record) external view returns (int256) {
    return IntStorage[keccak256(abi.encodePacked(record))];
  }

  function setIntValue(string record, int256 value) external onlyAdmins {
    IntStorage[keccak256(abi.encodePacked(record))] = value;
  }
}

contract configurable {
  function configureFromStorage() public returns (bool);
}

contract displayable {
  function bytes32ToString(bytes32 x) public pure returns (string) {
    bytes memory bytesString = new bytes(32);
    uint256 charCount = 0;
    for (uint256 j = 0; j < 32; j++) {
      if (x[j] != 0) {
        bytesString[charCount] = x[j];
        charCount++;
      }
    }
    bytes memory bytesStringTrimmed = new bytes(charCount);
    for (j = 0; j < charCount; j++) {
      bytesStringTrimmed[j] = bytesString[j];
    }
    return string(bytesStringTrimmed);
  }
}

contract freezable is administratable {
  using SafeMath for uint256;

  bool public frozenToken;
  // TODO move this into external storage
  address[] public frozenAccountForIndex;
  mapping (address => bool) public frozenAccount;
  mapping (address => bool) private processedAccount;

  event FrozenFunds(address indexed target, bool frozen);
  event FrozenToken(bool frozen);

  modifier unlessFrozen {
    require(!frozenToken);
    require(!frozenAccount[msg.sender]);
    _;
  }

  function totalFrozenAccountsMapping() public view returns(uint256) {
    return frozenAccountForIndex.length;
  }

  function freezeAccount(address target, bool freeze) public onlySuperAdmins {
    frozenAccount[target] = freeze;
    if (!processedAccount[target]) {
      frozenAccountForIndex.push(target);
      processedAccount[target] = true;
    }
    emit FrozenFunds(target, freeze);
  }

  function freezeToken(bool freeze) public onlySuperAdmins {
    frozenToken = freeze;
    emit FrozenToken(frozenToken);
  }

}

contract IStorable {
  function getLedgerNameHash() external view returns (bytes32);
  function getStorageNameHash() external view returns (bytes32);
}

contract upgradeable is administratable {
  address public predecessor;
  address public successor;
  bool public isTokenContract;
  string public version;

  event Upgraded(address indexed successor);
  event UpgradedFrom(address indexed predecessor);
  event Transfer(address indexed _from, address indexed _to, uint256 _value);

  modifier unlessUpgraded() {
    if (msg.sender != successor && successor != address(0)) revert();
    _;
  }

  modifier isUpgraded() {
    if (successor == address(0)) revert();
    _;
  }

  modifier hasPredecessor() {
    if (predecessor == address(0)) revert();
    _;
  }

  function isDeprecated() public view returns (bool) {
    return successor != address(0);
  }

  function upgradeTo(address _successor, uint256 remainingContractBalance) public onlySuperAdmins unlessUpgraded returns (bool){
    require(_successor != address(0));
    successor = _successor;
    if (remainingContractBalance > 0) {
      emit Transfer(this, _successor, remainingContractBalance);
    }

    emit Upgraded(_successor);
    return true;
  }

  function upgradedFrom(address _predecessor) public onlySuperAdmins returns (bool) {
    require(_predecessor != address(0));

    predecessor = _predecessor;

    emit UpgradedFrom(_predecessor);

    // TODO refactor this into registry contract when ready for registry upgrade
    if (upgradeable(_predecessor).predecessor() != address(0)) {
      if (upgradeable(_predecessor).isTokenContract()) {
        emit Transfer(_predecessor, this, ERC20(_predecessor).balanceOf(_predecessor));
      }
    } else {
      emit Transfer(this, this, 0); // make etherscan see this as an ERC-20. lets remove in v3
    }

    return true;
  }
}

contract CardStackToken is ERC20,
                           freezable,
                           displayable,
                           upgradeable,
                           configurable,
                           IStorable {

  using SafeMath for uint256;
  using CstLibrary for address;

  ITokenLedger public tokenLedger;
  string public storageName;
  string public ledgerName;
  address public externalStorage;
  address public registry;
  uint8 public constant decimals = 18;
  bool public isTokenContract = true;
  bool public haltPurchase;

  // This state is specific to the first version of the CST
  // token contract and the token generation event, and hence
  // there is no reason to persist in external storage for
  // future contracts.
  bool public allowTransfers;
  mapping (address => bool) public whitelistedTransferer;
  address[] public whitelistedTransfererForIndex;
  mapping (address => bool) private processedWhitelistedTransferer;
  uint256 public contributionMinimum;

  event Mint(uint256 amountMinted, uint256 totalTokens, uint256 circulationCap);
  event Approval(address indexed _owner,
                 address indexed _spender,
                 uint256 _value);
  event Transfer(address indexed _from,
                 address indexed _to,
                 uint256 _value);
  event WhiteList(address indexed buyer, uint256 holdCap);
  event ConfigChanged(uint256 buyPrice, uint256 circulationCap, uint256 balanceLimit);
  event VestedTokenGrant(address indexed beneficiary, uint256 startDate, uint256 cliffDate, uint256 durationSec, uint256 fullyVestedAmount, bool isRevocable);
  event VestedTokenRevocation(address indexed beneficiary);
  event VestedTokenRelease(address indexed beneficiary, uint256 amount);
  event StorageUpdated(address storageAddress, address ledgerAddress);
  event PurchaseHalted();
  event PurchaseResumed();

  modifier onlyFoundation {
    address foundation = externalStorage.getFoundation();
    require(foundation != address(0));
    if (msg.sender != owner && msg.sender != foundation) revert();
    _;
  }

  modifier initStorage {
    address ledgerAddress = Registry(registry).getStorage(ledgerName);
    address storageAddress = Registry(registry).getStorage(storageName);

    tokenLedger = ITokenLedger(ledgerAddress);
    externalStorage = storageAddress;
    _;
  }

  constructor(address _registry, string _storageName, string _ledgerName) public payable {
    isTokenContract = true;
    version = "2";
    require(_registry != address(0));
    storageName = _storageName;
    ledgerName = _ledgerName;
    registry = _registry;

    addSuperAdmin(registry);
  }

  /* This unnamed function is called whenever someone tries to send ether directly to the token contract */
  function () public {
    revert(); // Prevents accidental sending of ether
  }

  function getLedgerNameHash() external view returns (bytes32) {
    return keccak256(abi.encodePacked(ledgerName));
  }

  function getStorageNameHash() external view returns (bytes32) {
    return keccak256(abi.encodePacked(storageName));
  }

  function configure(bytes32 _tokenName,
                     bytes32 _tokenSymbol,
                     uint256 _buyPrice,
                     uint256 _circulationCap,
                     uint256 _balanceLimit,
                     address _foundation) public onlySuperAdmins initStorage returns (bool) {

    uint256 __buyPrice= externalStorage.getBuyPrice();
    if (__buyPrice> 0 && __buyPrice!= _buyPrice) {
      require(frozenToken);
    }

    externalStorage.setTokenName(_tokenName);
    externalStorage.setTokenSymbol(_tokenSymbol);
    externalStorage.setBuyPrice(_buyPrice);
    externalStorage.setCirculationCap(_circulationCap);
    externalStorage.setFoundation(_foundation);
    externalStorage.setBalanceLimit(_balanceLimit);

    emit ConfigChanged(_buyPrice, _circulationCap, _balanceLimit);

    return true;
  }

  function configureFromStorage() public onlySuperAdmins unlessUpgraded initStorage returns (bool) {
    freezeToken(true);
    return true;
  }

  function updateStorage(string newStorageName, string newLedgerName) public onlySuperAdmins unlessUpgraded returns (bool) {
    require(frozenToken);

    storageName = newStorageName;
    ledgerName = newLedgerName;

    configureFromStorage();

    address ledgerAddress = Registry(registry).getStorage(ledgerName);
    address storageAddress = Registry(registry).getStorage(storageName);
    emit StorageUpdated(storageAddress, ledgerAddress);
    return true;
  }

  function name() public view unlessUpgraded returns(string) {
    return bytes32ToString(externalStorage.getTokenName());
  }

  function symbol() public view unlessUpgraded returns(string) {
    return bytes32ToString(externalStorage.getTokenSymbol());
  }

  function totalInCirculation() public view unlessUpgraded returns(uint256) {
    return tokenLedger.totalInCirculation().add(totalUnvestedAndUnreleasedTokens());
  }

  function cstBalanceLimit() public view unlessUpgraded returns(uint256) {
    return externalStorage.getBalanceLimit();
  }

  function buyPrice() public view unlessUpgraded returns(uint256) {
    return externalStorage.getBuyPrice();
  }

  function circulationCap() public view unlessUpgraded returns(uint256) {
    return externalStorage.getCirculationCap();
  }

  // intentionally allowing this to be visible if upgraded so foundation can
  // withdraw funds from contract that has a successor
  function foundation() public view returns(address) {
    return externalStorage.getFoundation();
  }

  function totalSupply() public view unlessUpgraded returns(uint256) {
    return tokenLedger.totalTokens();
  }

  function tokensAvailable() public view unlessUpgraded returns(uint256) {
    return totalSupply().sub(totalInCirculation());
  }

  function balanceOf(address account) public view unlessUpgraded returns (uint256) {
    address thisAddress = this;
    if (thisAddress == account) {
      return tokensAvailable();
    } else {
      return tokenLedger.balanceOf(account);
    }
  }

  function transfer(address recipient, uint256 amount) public unlessFrozen unlessUpgraded returns (bool) {
    require(allowTransfers || whitelistedTransferer[msg.sender]);
    require(amount > 0);
    require(!frozenAccount[recipient]);

    tokenLedger.transfer(msg.sender, recipient, amount);
    emit Transfer(msg.sender, recipient, amount);

    return true;
  }

  function mintTokens(uint256 mintedAmount) public onlySuperAdmins unlessUpgraded returns (bool) {
    uint256 _circulationCap = externalStorage.getCirculationCap();
    tokenLedger.mintTokens(mintedAmount);

    emit Mint(mintedAmount, tokenLedger.totalTokens(), _circulationCap);

    emit Transfer(address(0), this, mintedAmount);

    return true;
  }

  function grantTokens(address recipient, uint256 amount) public onlySuperAdmins unlessUpgraded returns (bool) {
    require(amount <= tokensAvailable());
    require(!frozenAccount[recipient]);

    tokenLedger.debitAccount(recipient, amount);
    emit Transfer(this, recipient, amount);

    return true;
  }

  function setHaltPurchase(bool _haltPurchase) public onlySuperAdmins unlessUpgraded returns (bool) {
    haltPurchase = _haltPurchase;

    if (_haltPurchase) {
      emit PurchaseHalted();
    } else {
      emit PurchaseResumed();
    }
    return true;
  }

  function buy() external payable unlessFrozen unlessUpgraded returns (uint256) {
    require(!haltPurchase);
    require(externalStorage.getApprovedBuyer(msg.sender));

    uint256 _buyPriceTokensPerWei = externalStorage.getBuyPrice();
    uint256 _circulationCap = externalStorage.getCirculationCap();
    require(msg.value > 0);
    require(_buyPriceTokensPerWei > 0);
    require(_circulationCap > 0);

    uint256 amount = msg.value.mul(_buyPriceTokensPerWei);
    require(totalInCirculation().add(amount) <= _circulationCap);
    require(amount <= tokensAvailable());

    uint256 balanceLimit;
    uint256 buyerBalance = tokenLedger.balanceOf(msg.sender);
    uint256 customLimit = externalStorage.getCustomBuyerLimit(msg.sender);
    require(contributionMinimum == 0 || buyerBalance.add(amount) >= contributionMinimum);

    if (customLimit > 0) {
      balanceLimit = customLimit;
    } else {
      balanceLimit = externalStorage.getBalanceLimit();
    }

    require(balanceLimit > 0 && balanceLimit >= buyerBalance.add(amount));

    tokenLedger.debitAccount(msg.sender, amount);
    emit Transfer(this, msg.sender, amount);

    return amount;
  }

  // intentionally allowing this to be visible if upgraded so foundation can
  // withdraw funds from contract that has a successor
  function foundationWithdraw(uint256 amount) public onlyFoundation returns (bool) {
    /* UNTRUSTED */
    msg.sender.transfer(amount);

    return true;
  }

  function foundationDeposit() public payable unlessUpgraded returns (bool) {
    return true;
  }

  function allowance(address owner, address spender) public view unlessUpgraded returns (uint256) {
    return externalStorage.getAllowance(owner, spender);
  }

  function transferFrom(address from, address to, uint256 value) public unlessFrozen unlessUpgraded returns (bool) {
    require(allowTransfers);
    require(!frozenAccount[from]);
    require(!frozenAccount[to]);
    require(from != msg.sender);
    require(value > 0);

    uint256 allowanceValue = allowance(from, msg.sender);
    require(allowanceValue >= value);

    tokenLedger.transfer(from, to, value);
    externalStorage.setAllowance(from, msg.sender, allowanceValue.sub(value));

    emit Transfer(from, to, value);
    return true;
  }

  /* 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
   *
   * Please use `increaseApproval` or `decreaseApproval` instead.
   */
  function approve(address spender, uint256 value) public unlessFrozen unlessUpgraded returns (bool) {
    require(spender != address(0));
    require(!frozenAccount[spender]);
    require(msg.sender != spender);

    externalStorage.setAllowance(msg.sender, spender, value);

    emit Approval(msg.sender, spender, value);
    return true;
  }

  function increaseApproval(address spender, uint256 addedValue) public unlessFrozen unlessUpgraded returns (bool) {
    return approve(spender, externalStorage.getAllowance(msg.sender, spender).add(addedValue));
  }

  function decreaseApproval(address spender, uint256 subtractedValue) public unlessFrozen unlessUpgraded returns (bool) {
    uint256 oldValue = externalStorage.getAllowance(msg.sender, spender);

    if (subtractedValue > oldValue) {
      return approve(spender, 0);
    } else {
      return approve(spender, oldValue.sub(subtractedValue));
    }
  }

  function grantVestedTokens(address beneficiary,
                             uint256 fullyVestedAmount,
                             uint256 startDate, // 0 indicates start "now"
                             uint256 cliffSec,
                             uint256 durationSec,
                             bool isRevocable) public onlySuperAdmins unlessUpgraded returns(bool) {

    uint256 _circulationCap = externalStorage.getCirculationCap();

    require(beneficiary != address(0));
    require(!frozenAccount[beneficiary]);
    require(durationSec >= cliffSec);
    require(totalInCirculation().add(fullyVestedAmount) <= _circulationCap);
    require(fullyVestedAmount <= tokensAvailable());

    uint256 _now = now;
    if (startDate == 0) {
      startDate = _now;
    }

    uint256 cliffDate = startDate.add(cliffSec);

    externalStorage.setVestingSchedule(beneficiary,
                                       fullyVestedAmount,
                                       startDate,
                                       cliffDate,
                                       durationSec,
                                       isRevocable);

    emit VestedTokenGrant(beneficiary, startDate, cliffDate, durationSec, fullyVestedAmount, isRevocable);

    return true;
  }


  function revokeVesting(address beneficiary) public onlySuperAdmins unlessUpgraded returns (bool) {
    require(beneficiary != address(0));
    externalStorage.revokeVesting(beneficiary);

    releaseVestedTokensForBeneficiary(beneficiary);

    emit VestedTokenRevocation(beneficiary);

    return true;
  }

  function releaseVestedTokens() public unlessFrozen unlessUpgraded returns (bool) {
    return releaseVestedTokensForBeneficiary(msg.sender);
  }

  function releaseVestedTokensForBeneficiary(address beneficiary) public unlessFrozen unlessUpgraded returns (bool) {
    require(beneficiary != address(0));
    require(!frozenAccount[beneficiary]);

    uint256 unreleased = releasableAmount(beneficiary);

    if (unreleased == 0) { return true; }

    externalStorage.releaseVestedTokens(beneficiary);

    tokenLedger.debitAccount(beneficiary, unreleased);
    emit Transfer(this, beneficiary, unreleased);

    emit VestedTokenRelease(beneficiary, unreleased);

    return true;
  }

  function releasableAmount(address beneficiary) public view unlessUpgraded returns (uint256) {
    return externalStorage.releasableAmount(beneficiary);
  }

  function totalUnvestedAndUnreleasedTokens() public view unlessUpgraded returns (uint256) {
    return externalStorage.getTotalUnvestedAndUnreleasedTokens();
  }

  function vestingMappingSize() public view unlessUpgraded returns (uint256) {
    return externalStorage.vestingMappingSize();
  }

  function vestingBeneficiaryForIndex(uint256 index) public view unlessUpgraded returns (address) {
    return externalStorage.vestingBeneficiaryForIndex(index);
  }

  function vestingSchedule(address _beneficiary) public
                                                 view unlessUpgraded returns (uint256 startDate,
                                                                              uint256 cliffDate,
                                                                              uint256 durationSec,
                                                                              uint256 fullyVestedAmount,
                                                                              uint256 vestedAmount,
                                                                              uint256 vestedAvailableAmount,
                                                                              uint256 releasedAmount,
                                                                              uint256 revokeDate,
                                                                              bool isRevocable) {
    (
      startDate,
      cliffDate,
      durationSec,
      fullyVestedAmount,
      releasedAmount,
      revokeDate,
      isRevocable
    ) =  externalStorage.getVestingSchedule(_beneficiary);

    vestedAmount = externalStorage.vestedAmount(_beneficiary);
    vestedAvailableAmount = externalStorage.vestedAvailableAmount(_beneficiary);
  }

  function totalCustomBuyersMapping() public view returns (uint256) {
    return externalStorage.getCustomBuyerMappingCount();
  }

  function customBuyerLimit(address buyer) public view returns (uint256) {
    return externalStorage.getCustomBuyerLimit(buyer);
  }

  function customBuyerForIndex(uint256 index) public view returns (address) {
    return externalStorage.getCustomBuyerForIndex(index);
  }

  function setCustomBuyer(address buyer, uint256 balanceLimit) public onlySuperAdmins unlessUpgraded returns (bool) {
    require(buyer != address(0));
    externalStorage.setCustomBuyerLimit(buyer, balanceLimit);
    addBuyer(buyer);

    return true;
  }

  function setAllowTransfers(bool _allowTransfers) public onlySuperAdmins unlessUpgraded returns (bool) {
    allowTransfers = _allowTransfers;
    return true;
  }

  function setContributionMinimum(uint256 _contributionMinimum) public onlySuperAdmins unlessUpgraded returns (bool) {
    contributionMinimum = _contributionMinimum;
    return true;
  }

  function totalBuyersMapping() public view returns (uint256) {
    return externalStorage.getApprovedBuyerMappingCount();
  }

  function approvedBuyer(address buyer) public view returns (bool) {
    return externalStorage.getApprovedBuyer(buyer);
  }

  function approvedBuyerForIndex(uint256 index) public view returns (address) {
    return externalStorage.getApprovedBuyerForIndex(index);
  }

  function addBuyer(address buyer) public onlySuperAdmins unlessUpgraded returns (bool) {
    require(buyer != address(0));
    externalStorage.setApprovedBuyer(buyer, true);

    uint256 balanceLimit = externalStorage.getCustomBuyerLimit(buyer);
    if (balanceLimit == 0) {
      balanceLimit = externalStorage.getBalanceLimit();
    }

    emit WhiteList(buyer, balanceLimit);

    return true;
  }

  function removeBuyer(address buyer) public onlySuperAdmins unlessUpgraded returns (bool) {
    require(buyer != address(0));
    externalStorage.setApprovedBuyer(buyer, false);

    return true;
  }

  function totalTransferWhitelistMapping() public view returns (uint256) {
    return whitelistedTransfererForIndex.length;
  }

  function setWhitelistedTransferer(address transferer, bool _allowTransfers) public onlySuperAdmins unlessUpgraded returns (bool) {
    require(transferer != address(0));
    whitelistedTransferer[transferer] = _allowTransfers;
    if (!processedWhitelistedTransferer[transferer]) {
      whitelistedTransfererForIndex.push(transferer);
      processedWhitelistedTransferer[transferer] = true;
    }

    return true;
  }
}

contract Registry is administratable, upgradeable {
  using SafeMath for uint256;

  bytes4 constant INTERFACE_META_ID = 0x01ffc9a7;
  bytes4 constant ADDR_INTERFACE_ID = 0x3b3b57de;
  bytes32 constant BARE_DOMAIN_NAMEHASH = 0x794941fae74d6435d1b29ee1c08cc39941ba78470872e6afd0693c7eeb63025c; // namehash for "cardstack.eth"

  mapping(bytes32 => address) public storageForHash;
  mapping(bytes32 => address) public contractForHash;
  mapping(bytes32 => bytes32) public hashForNamehash;
  mapping(bytes32 => bytes32) public namehashForHash;
  string[] public contractNameForIndex;

  event ContractRegistered(address indexed _contract, string _name, bytes32 namehash);
  event ContractUpgraded(address indexed successor, address indexed predecessor, string name, bytes32 namehash);
  event StorageAdded(address indexed storageAddress, string name);
  event StorageRemoved(address indexed storageAddress, string name);
  event AddrChanged(bytes32 indexed node, address a);

  function() public {
    revert();
  }

  function supportsInterface(bytes4 interfaceId) public pure returns (bool) {
    return interfaceId == ADDR_INTERFACE_ID ||
           interfaceId == INTERFACE_META_ID;
  }

  function addr(bytes32 node) public view returns (address) {
    return contractForHash[hashForNamehash[node]];
  }

  function getContractHash(string name) public view unlessUpgraded returns (bytes32) {
    return keccak256(abi.encodePacked(name));
  }

  function numContracts() public view returns(uint256) {
    return contractNameForIndex.length;
  }

  function setNamehash(string contractName, bytes32 namehash) external onlySuperAdmins unlessUpgraded returns (bool) {
    require(namehash != 0x0);

    bytes32 hash = keccak256(abi.encodePacked(contractName));
    address contractAddress = contractForHash[hash];

    require(contractAddress != 0x0);
    require(hashForNamehash[namehash] == 0x0);

    hashForNamehash[namehash] = hash;
    namehashForHash[hash] = namehash;

    emit AddrChanged(namehash, contractAddress);
  }

  function register(string name, address contractAddress, bytes32 namehash) external onlySuperAdmins unlessUpgraded returns (bool) {
    bytes32 hash = keccak256(abi.encodePacked(name));
    require(bytes(name).length > 0);
    require(contractAddress != 0x0);
    require(contractForHash[hash] == 0x0);
    require(hashForNamehash[namehash] == 0x0);

    contractNameForIndex.push(name);
    contractForHash[hash] = contractAddress;

    if (namehash != 0x0) {
      hashForNamehash[namehash] = hash;
      namehashForHash[hash] = namehash;
    }

    address storageAddress = storageForHash[IStorable(contractAddress).getStorageNameHash()];
    address ledgerAddress = storageForHash[IStorable(contractAddress).getLedgerNameHash()];

    if (storageAddress != 0x0) {
      ExternalStorage(storageAddress).addAdmin(contractAddress);
    }
    if (ledgerAddress != 0x0) {
      CstLedger(ledgerAddress).addAdmin(contractAddress);
    }

    configurable(contractAddress).configureFromStorage();

    emit ContractRegistered(contractAddress, name, namehash);

    if (namehash != 0x0) {
      emit AddrChanged(namehash, contractAddress);
    }

    return true;
  }

  function upgradeContract(string name, address successor) external onlySuperAdmins unlessUpgraded returns (bytes32) {
    bytes32 hash = keccak256(abi.encodePacked(name));
    require(successor != 0x0);
    require(contractForHash[hash] != 0x0);

    address predecessor = contractForHash[hash];
    require(freezable(predecessor).frozenToken());

    contractForHash[hash] = successor;

    uint256 remainingContractBalance;
    // we need https://github.com/ethereum/EIPs/issues/165
    // to be able to see if a contract is ERC20 or not...
    if (hash == keccak256("cst")) {
      remainingContractBalance = ERC20(predecessor).balanceOf(predecessor);
    }

    upgradeable(predecessor).upgradeTo(successor,
                                       remainingContractBalance);
    upgradeable(successor).upgradedFrom(predecessor);

    address successorStorageAddress = storageForHash[IStorable(successor).getStorageNameHash()];
    address successorLedgerAddress = storageForHash[IStorable(successor).getLedgerNameHash()];
    address predecessorStorageAddress = storageForHash[IStorable(predecessor).getStorageNameHash()];
    address predecessorLedgerAddress = storageForHash[IStorable(predecessor).getLedgerNameHash()];

    if (successorStorageAddress != 0x0) {
      ExternalStorage(successorStorageAddress).addAdmin(successor);
    }
    if (predecessorStorageAddress != 0x0) {
      ExternalStorage(predecessorStorageAddress).removeAdmin(predecessor);
    }

    if (successorLedgerAddress != 0x0) {
      CstLedger(successorLedgerAddress).addAdmin(successor);
    }
    if (predecessorLedgerAddress != 0x0) {
      CstLedger(predecessorLedgerAddress).removeAdmin(predecessor);
    }

    configurable(successor).configureFromStorage();

    if (hashForNamehash[BARE_DOMAIN_NAMEHASH] == hash) {
      emit AddrChanged(BARE_DOMAIN_NAMEHASH, successor);
    }
    if (namehashForHash[hash] != 0x0 && namehashForHash[hash] != BARE_DOMAIN_NAMEHASH) {
      emit AddrChanged(namehashForHash[hash], successor);
    }

    emit ContractUpgraded(successor, predecessor, name, namehashForHash[hash]);
    return hash;
  }

  function addStorage(string name, address storageAddress) external onlySuperAdmins unlessUpgraded {
    require(storageAddress != address(0));
    bytes32 hash = keccak256(abi.encodePacked(name));
    storageForHash[hash] = storageAddress;

    emit StorageAdded(storageAddress, name);
  }

  function getStorage(string name) public view unlessUpgraded returns (address) {
    return storageForHash[keccak256(abi.encodePacked(name))];
  }

  function removeStorage(string name) public onlySuperAdmins unlessUpgraded {
    address storageAddress = storageForHash[keccak256(abi.encodePacked(name))];
    delete storageForHash[keccak256(abi.encodePacked(name))];

    emit StorageRemoved(storageAddress, name);
  }
}

Contract Security Audit

Contract ABI

[{"constant":true,"inputs":[],"name":"totalAdminsMapping","outputs":[{"name":"","type":"uint256"}],"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":true,"inputs":[{"name":"buyer","type":"address"}],"name":"customBuyerLimit","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newStorageName","type":"string"},{"name":"newLedgerName","type":"string"}],"name":"updateStorage","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"beneficiary","type":"address"}],"name":"releasableAmount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"admin","type":"address"}],"name":"removeAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"configureFromStorage","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"allowTransfers","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"vestingMappingSize","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","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":true,"inputs":[],"name":"totalFrozenAccountsMapping","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"adminsForIndex","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenLedger","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"beneficiary","type":"address"}],"name":"revokeVesting","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"foundation","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"admins","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"index","type":"uint256"}],"name":"vestingBeneficiaryForIndex","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"admin","type":"address"}],"name":"removeSuperAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"contributionMinimum","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isTokenContract","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"transferer","type":"address"},{"name":"_allowTransfers","type":"bool"}],"name":"setWhitelistedTransferer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"releaseVestedTokens","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"version","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"circulationCap","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalInCirculation","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_tokenName","type":"bytes32"},{"name":"_tokenSymbol","type":"bytes32"},{"name":"_buyPrice","type":"uint256"},{"name":"_circulationCap","type":"uint256"},{"name":"_balanceLimit","type":"uint256"},{"name":"_foundation","type":"address"}],"name":"configure","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"tokensAvailable","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","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":"_predecessor","type":"address"}],"name":"upgradedFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_haltPurchase","type":"bool"}],"name":"setHaltPurchase","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"frozenToken","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"buyer","type":"address"}],"name":"removeBuyer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"successor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"admin","type":"address"}],"name":"addAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"freeze","type":"bool"}],"name":"freezeToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"registry","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"frozenAccountForIndex","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"cstBalanceLimit","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"buyPrice","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"externalStorage","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalUnvestedAndUnreleasedTokens","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getLedgerNameHash","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"x","type":"bytes32"}],"name":"bytes32ToString","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"mintedAmount","type":"uint256"}],"name":"mintTokens","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getStorageNameHash","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"beneficiary","type":"address"}],"name":"releaseVestedTokensForBeneficiary","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"foundationDeposit","outputs":[{"name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"whitelistedTransfererForIndex","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalBuyersMapping","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"buy","outputs":[{"name":"","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSuperAdminsMapping","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"superAdmins","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"admin","type":"address"}],"name":"addSuperAdmin","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"frozenAccount","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"predecessor","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"index","type":"uint256"}],"name":"customBuyerForIndex","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"buyer","type":"address"}],"name":"addBuyer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"buyer","type":"address"}],"name":"approvedBuyer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"superAdminsForIndex","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isDeprecated","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"recipient","type":"address"},{"name":"amount","type":"uint256"}],"name":"grantTokens","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_contributionMinimum","type":"uint256"}],"name":"setContributionMinimum","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"foundationWithdraw","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ledgerName","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"haltPurchase","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"storageName","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","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":false,"inputs":[{"name":"buyer","type":"address"},{"name":"balanceLimit","type":"uint256"}],"name":"setCustomBuyer","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":"_allowTransfers","type":"bool"}],"name":"setAllowTransfers","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalCustomBuyersMapping","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"target","type":"address"},{"name":"freeze","type":"bool"}],"name":"freezeAccount","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalTransferWhitelistMapping","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"whitelistedTransferer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"index","type":"uint256"}],"name":"approvedBuyerForIndex","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_successor","type":"address"},{"name":"remainingContractBalance","type":"uint256"}],"name":"upgradeTo","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"beneficiary","type":"address"},{"name":"fullyVestedAmount","type":"uint256"},{"name":"startDate","type":"uint256"},{"name":"cliffSec","type":"uint256"},{"name":"durationSec","type":"uint256"},{"name":"isRevocable","type":"bool"}],"name":"grantVestedTokens","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_beneficiary","type":"address"}],"name":"vestingSchedule","outputs":[{"name":"startDate","type":"uint256"},{"name":"cliffDate","type":"uint256"},{"name":"durationSec","type":"uint256"},{"name":"fullyVestedAmount","type":"uint256"},{"name":"vestedAmount","type":"uint256"},{"name":"vestedAvailableAmount","type":"uint256"},{"name":"releasedAmount","type":"uint256"},{"name":"revokeDate","type":"uint256"},{"name":"isRevocable","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_registry","type":"address"},{"name":"_storageName","type":"string"},{"name":"_ledgerName","type":"string"}],"payable":true,"stateMutability":"payable","type":"constructor"},{"payable":false,"stateMutability":"nonpayable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amountMinted","type":"uint256"},{"indexed":false,"name":"totalTokens","type":"uint256"},{"indexed":false,"name":"circulationCap","type":"uint256"}],"name":"Mint","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":"buyer","type":"address"},{"indexed":false,"name":"holdCap","type":"uint256"}],"name":"WhiteList","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"buyPrice","type":"uint256"},{"indexed":false,"name":"circulationCap","type":"uint256"},{"indexed":false,"name":"balanceLimit","type":"uint256"}],"name":"ConfigChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"beneficiary","type":"address"},{"indexed":false,"name":"startDate","type":"uint256"},{"indexed":false,"name":"cliffDate","type":"uint256"},{"indexed":false,"name":"durationSec","type":"uint256"},{"indexed":false,"name":"fullyVestedAmount","type":"uint256"},{"indexed":false,"name":"isRevocable","type":"bool"}],"name":"VestedTokenGrant","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"beneficiary","type":"address"}],"name":"VestedTokenRevocation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"beneficiary","type":"address"},{"indexed":false,"name":"amount","type":"uint256"}],"name":"VestedTokenRelease","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"storageAddress","type":"address"},{"indexed":false,"name":"ledgerAddress","type":"address"}],"name":"StorageUpdated","type":"event"},{"anonymous":false,"inputs":[],"name":"PurchaseHalted","type":"event"},{"anonymous":false,"inputs":[],"name":"PurchaseResumed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"successor","type":"address"}],"name":"Upgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"predecessor","type":"address"}],"name":"UpgradedFrom","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"target","type":"address"},{"indexed":false,"name":"frozen","type":"bool"}],"name":"FrozenFunds","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"frozen","type":"bool"}],"name":"FrozenToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"admin","type":"address"}],"name":"AddAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"admin","type":"address"}],"name":"RemoveAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"admin","type":"address"}],"name":"AddSuperAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"admin","type":"address"}],"name":"RemoveSuperAdmin","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"}]

608060408190526012805460a060020a60ff02191674010000000000000000000000000000000000000000179055620060733881900390819083398101604081815282516020808501518386015160008054600160a060020a031916331790556012805460a060020a60ff0219167401000000000000000000000000000000000000000017905584860190945260018086527f3200000000000000000000000000000000000000000000000000000000000000929095019182529194918201939290910191620000d291600d9162000274565b50600160a060020a0383161515620000e957600080fd5b8151620000fe90600f90602085019062000274565b5080516200011490601090602084019062000274565b5060128054600160a060020a031916600160a060020a0385811691909117918290556200014b911664010000000062000154810204565b50505062000319565b600054600160a060020a031633148015906200018057503360009081526004602052604090205460ff16155b156200018b57600080fd5b600160a060020a0381161515620001a157600080fd5b600160a060020a0381166000908152600460209081526040808320805460ff19166001179055600690915290205460ff1615156200023d576002805460018082019092557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace018054600160a060020a031916600160a060020a0384169081179091556000908152600660205260409020805460ff191690911790555b604051600160a060020a038216907ffba24c034afca607a35e1f221b154b3f8e1f88c7924c8a0a06755b70708c44d890600090a250565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620002b757805160ff1916838001178555620002e7565b82800160010185558215620002e7579182015b82811115620002e7578251825591602001919060010190620002ca565b50620002f5929150620002f9565b5090565b6200031691905b80821115620002f5576000815560010162000300565b90565b615d4a80620003296000396000f3006080604052600436106103d95763ffffffff60e060020a6000350416630489882e81146103eb57806306fdde0314610412578063095ea7b31461049c578063115f2be2146104d457806313bac8f2146104f55780631726cbc81461058c5780631785f53c146105ad57806318160ddd146105d05780631a841b1b146105e55780632185810b146105fa578063222101d11461060f57806323b872dd146106245780632b28d2d01461064e578063313ce56714610663578063313f2a211461068e5780633886c957146106c25780633b0da260146106d757806341fbb050146106f8578063429b62e51461070d5780634610a4481461072e5780634902e4aa146107465780634f2d7ab514610767578063503720851461077c57806352fb05611461079157806354dd1da4146107b757806354fd4d50146107cc57806356597e65146107e15780635cb0c16f146107f65780635da01a5b1461080b57806360659a921461083b578063661884631461085057806366e3cb68146108745780636a420bbc146108955780636df006f3146108af5780636f75b00c146108c45780636ff968c3146108e557806370480275146108fa57806370a082311461091b578063715018a61461093c578063771eee16146109515780637b1039991461096b5780637db6cc1b14610980578063820e79ed146109985780638620410b146109ad57806388d7cd97146109c25780638da5cb5b146109d75780638df388c1146109ec5780638f1d5f7e14610a015780639201de5514610a1657806395d89b4114610a2e57806397304ced14610a435780639860811114610a5b57806399817b4714610a705780639ae066b014610a91578063a106e8c914610a99578063a4453a9614610ab1578063a6f2ae3a14610ac6578063a9059cbb14610ace578063abf7b06314610af2578063ad25cb4214610b07578063b3292ff014610b28578063b414d4b614610b49578063b719d03214610b6a578063b9447f7e14610b7f578063bbf8980314610b97578063c3437e0614610bb8578063c389439814610bd9578063c717823014610bf1578063c94e643c14610c06578063cb0b7b0314610c2a578063cedcd77014610c42578063cf1f3dd714610c5a578063d28dcdea14610c6f578063d73c277c14610c84578063d73dd62314610c99578063da14c72314610cbd578063dd62ed3e14610ce1578063df50afa414610d08578063e01bc60b14610d22578063e724529c14610d37578063e86d86ea14610d5d578063ec5da72114610d72578063f2fde38b14610d93578063f69f8a5c14610db4578063f6b2b33414610dcc578063fc13566d14610df0578063ffff6b0414610e22575b3480156103e557600080fd5b50600080fd5b3480156103f757600080fd5b50610400610e8c565b60408051918252519081900360200190f35b34801561041e57600080fd5b50610427610e93565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610461578181015183820152602001610449565b50505050905090810190601f16801561048e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156104a857600080fd5b506104c0600160a060020a0360043516602435610f76565b604080519115158252519081900360200190f35b3480156104e057600080fd5b50610400600160a060020a0360043516611113565b34801561050157600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526104c094369492936024939284019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a9998810197919650918201945092508291508401838280828437509497506111c79650505050505050565b34801561059857600080fd5b50610400600160a060020a03600435166114aa565b3480156105b957600080fd5b506105ce600160a060020a036004351661155a565b005b3480156105dc57600080fd5b506104006115ed565b3480156105f157600080fd5b506104c06116a3565b34801561060657600080fd5b506104c0611937565b34801561061b57600080fd5b50610400611947565b34801561063057600080fd5b506104c0600160a060020a0360043581169060243516604435611a03565b34801561065a57600080fd5b50610400611c7c565b34801561066f57600080fd5b50610678611c82565b6040805160ff9092168252519081900360200190f35b34801561069a57600080fd5b506106a6600435611c87565b60408051600160a060020a039092168252519081900360200190f35b3480156106ce57600080fd5b506106a6611caf565b3480156106e357600080fd5b506104c0600160a060020a0360043516611cbe565b34801561070457600080fd5b506106a6611e14565b34801561071957600080fd5b506104c0600160a060020a0360043516611e8e565b34801561073a57600080fd5b506106a6600435611ea3565b34801561075257600080fd5b506105ce600160a060020a0360043516611f52565b34801561077357600080fd5b50610400611fe5565b34801561078857600080fd5b506104c0611feb565b34801561079d57600080fd5b506104c0600160a060020a0360043516602435151561200c565b3480156107c357600080fd5b506104c061212b565b3480156107d857600080fd5b50610427612193565b3480156107ed57600080fd5b50610400612221565b34801561080257600080fd5b506104006122b3565b34801561081757600080fd5b506104c0600435602435604435606435608435600160a060020a0360a4351661237b565b34801561084757600080fd5b50610400612a62565b34801561085c57600080fd5b506104c0600160a060020a0360043516602435612ab3565b34801561088057600080fd5b506104c0600160a060020a0360043516612c00565b3480156108a157600080fd5b506104c06004351515612e6c565b3480156108bb57600080fd5b506104c0612f76565b3480156108d057600080fd5b506104c0600160a060020a0360043516612f7f565b3480156108f157600080fd5b506106a661309e565b34801561090657600080fd5b506105ce600160a060020a03600435166130ad565b34801561092757600080fd5b50610400600160a060020a03600435166131c6565b34801561094857600080fd5b506105ce6132b9565b34801561095d57600080fd5b506105ce6004351515613318565b34801561097757600080fd5b506106a6613399565b34801561098c57600080fd5b506106a66004356133a8565b3480156109a457600080fd5b506104006133b6565b3480156109b957600080fd5b5061040061345e565b3480156109ce57600080fd5b506106a6613506565b3480156109e357600080fd5b506106a6613515565b3480156109f857600080fd5b50610400613524565b348015610a0d57600080fd5b506104006135cc565b348015610a2257600080fd5b506104276004356136a3565b348015610a3a57600080fd5b50610427613838565b348015610a4f57600080fd5b506104c06004356138e5565b348015610a6757600080fd5b50610400613b48565b348015610a7c57600080fd5b506104c0600160a060020a0360043516613b88565b6104c0613dd1565b348015610aa557600080fd5b506106a6600435613e09565b348015610abd57600080fd5b50610400613e17565b610400613e91565b348015610ada57600080fd5b506104c0600160a060020a036004351660243561447d565b348015610afe57600080fd5b50610400614604565b348015610b1357600080fd5b506104c0600160a060020a036004351661460a565b348015610b3457600080fd5b506105ce600160a060020a036004351661461f565b348015610b5557600080fd5b506104c0600160a060020a036004351661473b565b348015610b7657600080fd5b506106a6614750565b348015610b8b57600080fd5b506106a660043561475f565b348015610ba357600080fd5b506104c0600160a060020a03600435166147e0565b348015610bc457600080fd5b506104c0600160a060020a0360043516614a99565b348015610be557600080fd5b506106a6600435614b1b565b348015610bfd57600080fd5b506104c0614b29565b348015610c1257600080fd5b506104c0600160a060020a0360043516602435614b3a565b348015610c3657600080fd5b506104c0600435614c96565b348015610c4e57600080fd5b506104c0600435614d04565b348015610c6657600080fd5b50610427614e27565b348015610c7b57600080fd5b506104c0614e82565b348015610c9057600080fd5b50610427614ea4565b348015610ca557600080fd5b506104c0600160a060020a0360043516602435614eff565b348015610cc957600080fd5b506104c0600160a060020a0360043516602435615009565b348015610ced57600080fd5b50610400600160a060020a0360043581169060243516615129565b348015610d1457600080fd5b506104c06004351515615214565b348015610d2e57600080fd5b506104006152ad565b348015610d4357600080fd5b506105ce600160a060020a03600435166024351515615327565b348015610d6957600080fd5b5061040061543d565b348015610d7e57600080fd5b506104c0600160a060020a0360043516615443565b348015610d9f57600080fd5b506105ce600160a060020a0360043516615458565b348015610dc057600080fd5b506106a660043561547b565b348015610dd857600080fd5b506104c0600160a060020a03600435166024356154fc565b348015610dfc57600080fd5b506104c0600160a060020a036004351660243560443560643560843560a4351515615606565b348015610e2e57600080fd5b50610e43600160a060020a03600435166158ba565b60408051998a5260208a0198909852888801969096526060880194909452608087019290925260a086015260c085015260e0840152151561010083015251908190036101200190f35b6001545b90565b600c54606090600160a060020a03163314801590610ebb5750600c54600160a060020a031615155b15610ec557600080fd5b601154604080517f6f0fccab000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251610f7191735f4928c421a53a9aa161d96886299ded68fb76a291636f0fccab91602480820192602092909190829003018186803b158015610f4057600080fd5b505af4158015610f54573d6000803e3d6000fd5b505050506040513d6020811015610f6a57600080fd5b50516136a3565b905090565b60075460009060ff1615610f8957600080fd5b3360009081526009602052604090205460ff1615610fa657600080fd5b600c54600160a060020a03163314801590610fcb5750600c54600160a060020a031615155b15610fd557600080fd5b600160a060020a0383161515610fea57600080fd5b600160a060020a03831660009081526009602052604090205460ff161561101057600080fd5b33600160a060020a038416141561102657600080fd5b601154604080517fa7070373000000000000000000000000000000000000000000000000000000008152600160a060020a03928316600482015233602482015291851660448301526064820184905251735f4928c421a53a9aa161d96886299ded68fb76a29163a7070373916084808301926000929190829003018186803b1580156110b157600080fd5b505af41580156110c5573d6000803e3d6000fd5b5050604080518581529051600160a060020a03871693503392507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b92915050565b601154604080517fddf9d613000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152918316602483015251600091735f4928c421a53a9aa161d96886299ded68fb76a29163ddf9d61391604480820192602092909190829003018186803b15801561119557600080fd5b505af41580156111a9573d6000803e3d6000fd5b505050506040513d60208110156111bf57600080fd5b505192915050565b6000805481908190600160a060020a031633148015906111f757503360009081526004602052604090205460ff16155b1561120157600080fd5b600c54600160a060020a031633148015906112265750600c54600160a060020a031615155b1561123057600080fd5b60075460ff16151561124157600080fd5b845161125490600f906020880190615c66565b508351611268906010906020870190615c66565b506112716116a3565b5060125460405160e160020a6328cf2aed028152602060048201908152601080546002600019600183161561010002019091160460248401819052600160a060020a039094169363519e55da939192918291604490910190849080156113185780601f106112ed57610100808354040283529160200191611318565b820191906000526020600020905b8154815290600101906020018083116112fb57829003601f168201915b505092505050602060405180830381600087803b15801561133857600080fd5b505af115801561134c573d6000803e3d6000fd5b505050506040513d602081101561136257600080fd5b505160125460405160e160020a6328cf2aed028152602060048201908152600f80546002600019600183161561010002019091160460248401819052949650600160a060020a039093169363519e55da939282916044909101908490801561140b5780601f106113e05761010080835404028352916020019161140b565b820191906000526020600020905b8154815290600101906020018083116113ee57829003601f168201915b505092505050602060405180830381600087803b15801561142b57600080fd5b505af115801561143f573d6000803e3d6000fd5b505050506040513d602081101561145557600080fd5b505160408051600160a060020a0380841682528516602082015281519293507f8e2c71dfeb156b7c7d03fa7cba1af111d058c575816f578cb3c2d8c6be99e0ca929081900390910190a1506001949350505050565b600c54600090600160a060020a031633148015906114d25750600c54600160a060020a031615155b156114dc57600080fd5b601154604080517f7243cfbb000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152918416602483015251735f4928c421a53a9aa161d96886299ded68fb76a291637243cfbb916044808301926020929190829003018186803b15801561119557600080fd5b600054600160a060020a0316331480159061158557503360009081526004602052604090205460ff16155b1561158f57600080fd5b600160a060020a03811615156115a457600080fd5b600160a060020a038116600081815260036020526040808220805460ff19169055517f753f40ca3312b2408759a67875b367955e7baa221daf08aa3d643d96202ac12b9190a250565b600c54600090600160a060020a031633148015906116155750600c54600160a060020a031615155b1561161f57600080fd5b600e60009054906101000a9004600160a060020a0316600160a060020a0316637e1c0c096040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561167257600080fd5b505af1158015611686573d6000803e3d6000fd5b505050506040513d602081101561169c57600080fd5b5051905090565b60008054600160a060020a031633148015906116cf57503360009081526004602052604090205460ff16155b156116d957600080fd5b600c54600160a060020a031633148015906116fe5750600c54600160a060020a031615155b1561170857600080fd5b60125460405160e160020a6328cf2aed0281526020600482019081526010805460026000196001831615610100020190911604602484018190526000948594600160a060020a039091169363519e55da939290918291604490910190849080156117b35780601f10611788576101008083540402835291602001916117b3565b820191906000526020600020905b81548152906001019060200180831161179657829003601f168201915b505092505050602060405180830381600087803b1580156117d357600080fd5b505af11580156117e7573d6000803e3d6000fd5b505050506040513d60208110156117fd57600080fd5b505160125460405160e160020a6328cf2aed028152602060048201908152600f80546002600019600183161561010002019091160460248401819052949650600160a060020a039093169363519e55da93928291604490910190849080156118a65780601f1061187b576101008083540402835291602001916118a6565b820191906000526020600020905b81548152906001019060200180831161188957829003601f168201915b505092505050602060405180830381600087803b1580156118c657600080fd5b505af11580156118da573d6000803e3d6000fd5b505050506040513d60208110156118f057600080fd5b5051600e8054600160a060020a03808616600160a060020a0319928316179092556011805492841692909116919091179055905061192e6001613318565b60019250505090565b60125460b060020a900460ff1681565b600c54600090600160a060020a0316331480159061196f5750600c54600160a060020a031615155b1561197957600080fd5b601154604080517f0b96406a000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251735f4928c421a53a9aa161d96886299ded68fb76a291630b96406a916024808301926020929190829003018186803b1580156119ef57600080fd5b505af4158015611686573d6000803e3d6000fd5b600754600090819060ff1615611a1857600080fd5b3360009081526009602052604090205460ff1615611a3557600080fd5b600c54600160a060020a03163314801590611a5a5750600c54600160a060020a031615155b15611a6457600080fd5b60125460b060020a900460ff161515611a7c57600080fd5b600160a060020a03851660009081526009602052604090205460ff1615611aa257600080fd5b600160a060020a03841660009081526009602052604090205460ff1615611ac857600080fd5b600160a060020a038516331415611ade57600080fd5b60008311611aeb57600080fd5b611af58533615129565b905082811015611b0457600080fd5b600e54604080517fbeabacc8000000000000000000000000000000000000000000000000000000008152600160a060020a0388811660048301528781166024830152604482018790529151919092169163beabacc891606480830192600092919082900301818387803b158015611b7a57600080fd5b505af1158015611b8e573d6000803e3d6000fd5b5050601154735f4928c421a53a9aa161d96886299ded68fb76a2925063a70703739150600160a060020a03168733611bcc868963ffffffff615bae16565b6040805160e060020a63ffffffff8816028152600160a060020a0395861660048201529385166024850152919093166044830152606482019290925290516084808301926000929190829003018186803b158015611c2957600080fd5b505af4158015611c3d573d6000803e3d6000fd5b5050604080518681529051600160a060020a03808916945089169250600080516020615cff8339815191529181900360200190a3506001949350505050565b60085490565b601281565b6001805482908110611c9557fe5b600091825260209091200154600160a060020a0316905081565b600e54600160a060020a031681565b60008054600160a060020a03163314801590611cea57503360009081526004602052604090205460ff16155b15611cf457600080fd5b600c54600160a060020a03163314801590611d195750600c54600160a060020a031615155b15611d2357600080fd5b600160a060020a0382161515611d3857600080fd5b601154604080517f3613b781000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152918416602483015251735f4928c421a53a9aa161d96886299ded68fb76a291633613b781916044808301926000929190829003018186803b158015611db657600080fd5b505af4158015611dca573d6000803e3d6000fd5b50505050611dd782613b88565b50604051600160a060020a038316907fe8a24516e1d3bae0c4742f4e5ded148733d2193d648d57d54bbec9c20e4b444990600090a2506001919050565b601154604080517f96468249000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251600091735f4928c421a53a9aa161d96886299ded68fb76a291639646824991602480820192602092909190829003018186803b1580156119ef57600080fd5b60036020526000908152604090205460ff1681565b600c54600090600160a060020a03163314801590611ecb5750600c54600160a060020a031615155b15611ed557600080fd5b601154604080517f52bafbfa000000000000000000000000000000000000000000000000000000008152600160a060020a0390921660048301526024820184905251735f4928c421a53a9aa161d96886299ded68fb76a2916352bafbfa916044808301926020929190829003018186803b15801561119557600080fd5b600054600160a060020a03163314801590611f7d57503360009081526004602052604090205460ff16155b15611f8757600080fd5b600160a060020a0381161515611f9c57600080fd5b600160a060020a038116600081815260046020526040808220805460ff19169055517f1aaaaf7609619e631f47eb3546f9fdd8c61b1af2175988a0ddb9a06680c3b9ed9190a250565b60165481565b60125474010000000000000000000000000000000000000000900460ff1681565b60008054600160a060020a0316331480159061203857503360009081526004602052604090205460ff16155b1561204257600080fd5b600c54600160a060020a031633148015906120675750600c54600160a060020a031615155b1561207157600080fd5b600160a060020a038316151561208657600080fd5b600160a060020a0383166000908152601360209081526040808320805460ff1916861515179055601590915290205460ff161515612122576014805460018082019092557fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec018054600160a060020a031916600160a060020a0386169081179091556000908152601560205260409020805460ff191690911790555b50600192915050565b60075460009060ff161561213e57600080fd5b3360009081526009602052604090205460ff161561215b57600080fd5b600c54600160a060020a031633148015906121805750600c54600160a060020a031615155b1561218a57600080fd5b610f7133613b88565b600d805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156122195780601f106121ee57610100808354040283529160200191612219565b820191906000526020600020905b8154815290600101906020018083116121fc57829003601f168201915b505050505081565b600c54600090600160a060020a031633148015906122495750600c54600160a060020a031615155b1561225357600080fd5b6011546040805160e160020a635ac01573028152600160a060020a03909216600483015251735f4928c421a53a9aa161d96886299ded68fb76a29163b5802ae6916024808301926020929190829003018186803b1580156119ef57600080fd5b600c54600090600160a060020a031633148015906122db5750600c54600160a060020a031615155b156122e557600080fd5b610f716122f0613524565b600e60009054906101000a9004600160a060020a0316600160a060020a0316635cb0c16f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561234357600080fd5b505af1158015612357573d6000803e3d6000fd5b505050506040513d602081101561236d57600080fd5b50519063ffffffff615bc016565b600080548190600160a060020a031633148015906123a957503360009081526004602052604090205460ff16155b156123b357600080fd5b60125460405160e160020a6328cf2aed0281526020600482019081526010805460026000196001831615610100020190911604602484018190526000948594600160a060020a039091169363519e55da9392909182916044909101908490801561245e5780601f106124335761010080835404028352916020019161245e565b820191906000526020600020905b81548152906001019060200180831161244157829003601f168201915b505092505050602060405180830381600087803b15801561247e57600080fd5b505af1158015612492573d6000803e3d6000fd5b505050506040513d60208110156124a857600080fd5b505160125460405160e160020a6328cf2aed028152602060048201908152600f80546002600019600183161561010002019091160460248401819052949650600160a060020a039093169363519e55da93928291604490910190849080156125515780601f1061252657610100808354040283529160200191612551565b820191906000526020600020905b81548152906001019060200180831161253457829003601f168201915b505092505050602060405180830381600087803b15801561257157600080fd5b505af1158015612585573d6000803e3d6000fd5b505050506040513d602081101561259b57600080fd5b5051600e8054600160a060020a03808616600160a060020a0319928316179092556011805483851692169190911790819055604080517fcedc72770000000000000000000000000000000000000000000000000000000081529190921660048201529051919250735f4928c421a53a9aa161d96886299ded68fb76a29163cedc727791602480820192602092909190829003018186803b15801561263e57600080fd5b505af4158015612652573d6000803e3d6000fd5b505050506040513d602081101561266857600080fd5b5051925060008311801561267c5750878314155b156126925760075460ff16151561269257600080fd5b601154604080517f9c473bb2000000000000000000000000000000000000000000000000000000008152600160a060020a039092166004830152602482018c905251735f4928c421a53a9aa161d96886299ded68fb76a291639c473bb2916044808301926000929190829003018186803b15801561270f57600080fd5b505af4158015612723573d6000803e3d6000fd5b5050601154604080517fe6e623d5000000000000000000000000000000000000000000000000000000008152600160a060020a039092166004830152602482018d905251735f4928c421a53a9aa161d96886299ded68fb76a2935063e6e623d592506044808301926000929190829003018186803b1580156127a457600080fd5b505af41580156127b8573d6000803e3d6000fd5b5050601154604080517f1112b124000000000000000000000000000000000000000000000000000000008152600160a060020a039092166004830152602482018c905251735f4928c421a53a9aa161d96886299ded68fb76a29350631112b12492506044808301926000929190829003018186803b15801561283957600080fd5b505af415801561284d573d6000803e3d6000fd5b5050601154604080517fcd54c54e000000000000000000000000000000000000000000000000000000008152600160a060020a039092166004830152602482018b905251735f4928c421a53a9aa161d96886299ded68fb76a2935063cd54c54e92506044808301926000929190829003018186803b1580156128ce57600080fd5b505af41580156128e2573d6000803e3d6000fd5b5050601154604080517f05bf779f000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152918916602483015251735f4928c421a53a9aa161d96886299ded68fb76a293506305bf779f92506044808301926000929190829003018186803b15801561296457600080fd5b505af4158015612978573d6000803e3d6000fd5b5050601154604080517fdbafdbb6000000000000000000000000000000000000000000000000000000008152600160a060020a039092166004830152602482018a905251735f4928c421a53a9aa161d96886299ded68fb76a2935063dbafdbb692506044808301926000929190829003018186803b1580156129f957600080fd5b505af4158015612a0d573d6000803e3d6000fd5b5050604080518b8152602081018b90528082018a905290517f9d1a3ea811a60a1b2c08f8e30a09832514a3ec19ba354d73d8fe12ad66591cec9350908190036060019150a15060019998505050505050505050565b600c54600090600160a060020a03163314801590612a8a5750600c54600160a060020a031615155b15612a9457600080fd5b610f71612a9f6122b3565b612aa76115ed565b9063ffffffff615bae16565b600754600090819060ff1615612ac857600080fd5b3360009081526009602052604090205460ff1615612ae557600080fd5b600c54600160a060020a03163314801590612b0a5750600c54600160a060020a031615155b15612b1457600080fd5b601154604080517fe7092b41000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152336024820152918616604483015251735f4928c421a53a9aa161d96886299ded68fb76a29163e7092b41916064808301926020929190829003018186803b158015612b9857600080fd5b505af4158015612bac573d6000803e3d6000fd5b505050506040513d6020811015612bc257600080fd5b5051905080831115612be057612bd9846000610f76565b9150612bf9565b612bd984612bf4838663ffffffff615bae16565b610f76565b5092915050565b60008054600160a060020a03163314801590612c2c57503360009081526004602052604090205460ff16155b15612c3657600080fd5b600160a060020a0382161515612c4b57600080fd5b600b8054600160a060020a031916600160a060020a0384169081179091556040517f75c09cedaf6c35dc577b0fd0a8c77c569c84be03eae895084c7c60788eac7d6490600090a26000600160a060020a031682600160a060020a031663b719d0326040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015612cdb57600080fd5b505af1158015612cef573d6000803e3d6000fd5b505050506040513d6020811015612d0557600080fd5b5051600160a060020a031614612e3d5781600160a060020a031663503720856040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015612d5357600080fd5b505af1158015612d67573d6000803e3d6000fd5b505050506040513d6020811015612d7d57600080fd5b505115612e3857604080517f70a08231000000000000000000000000000000000000000000000000000000008152600160a060020a038416600482018190529151309291600080516020615cff8339815191529183916370a082319160248083019260209291908290030181600087803b158015612dfa57600080fd5b505af1158015612e0e573d6000803e3d6000fd5b505050506040513d6020811015612e2457600080fd5b505160408051918252519081900360200190a35b612e64565b6040805160008152905130918291600080516020615cff8339815191529181900360200190a35b506001919050565b60008054600160a060020a03163314801590612e9857503360009081526004602052604090205460ff16155b15612ea257600080fd5b600c54600160a060020a03163314801590612ec75750600c54600160a060020a031615155b15612ed157600080fd5b601280548315801575010000000000000000000000000000000000000000000275ff0000000000000000000000000000000000000000001990921691909117909155612f45576040517ff5eced797ccd723743102a9d898a1372f6bd7a0206c4facf99081b9471f5727290600090a1612e64565b6040517fd20fe4b54e307993c74930d195aa389bf91e188918e31ad1da29aad5a748a4d390600090a1506001919050565b60075460ff1681565b60008054600160a060020a03163314801590612fab57503360009081526004602052604090205460ff16155b15612fb557600080fd5b600c54600160a060020a03163314801590612fda5750600c54600160a060020a031615155b15612fe457600080fd5b600160a060020a0382161515612ff957600080fd5b601154604080517f6ace6dc8000000000000000000000000000000000000000000000000000000008152600160a060020a03928316600482015291841660248301526000604483018190529051735f4928c421a53a9aa161d96886299ded68fb76a292636ace6dc8926064808301939192829003018186803b15801561307e57600080fd5b505af4158015613092573d6000803e3d6000fd5b50600195945050505050565b600c54600160a060020a031681565b600054600160a060020a031633148015906130d857503360009081526004602052604090205460ff16155b156130e257600080fd5b600160a060020a03811615156130f757600080fd5b600160a060020a0381166000908152600360209081526040808320805460ff19166001179055600590915290205460ff16151561318f576001805480820182557fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6018054600160a060020a031916600160a060020a0384169081179091556000908152600560205260409020805460ff191690911790555b604051600160a060020a038216907fad6de4452a631e641cb59902236607946ce9272b9b981f2f80e8d129cb9084ba90600090a250565b600c546000908190600160a060020a031633148015906131f05750600c54600160a060020a031615155b156131fa57600080fd5b5030600160a060020a03831681141561321c57613215612a62565b91506132b3565b600e54604080517f70a08231000000000000000000000000000000000000000000000000000000008152600160a060020a038681166004830152915191909216916370a082319160248083019260209291908290030181600087803b15801561328457600080fd5b505af1158015613298573d6000803e3d6000fd5b505050506040513d60208110156132ae57600080fd5b505191505b50919050565b600054600160a060020a031633146132d057600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a260008054600160a060020a0319169055565b600054600160a060020a0316331480159061334357503360009081526004602052604090205460ff16155b1561334d57600080fd5b6007805460ff191682151517908190556040805160ff90921615158252517f1623ff1a4138a65cb1f44d1a94c034f7dd8c1e826fefb1f27f0898580601e68d916020908290030190a150565b601254600160a060020a031681565b6008805482908110611c9557fe5b600c54600090600160a060020a031633148015906133de5750600c54600160a060020a031615155b156133e857600080fd5b601154604080517fec7c637d000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251735f4928c421a53a9aa161d96886299ded68fb76a29163ec7c637d916024808301926020929190829003018186803b1580156119ef57600080fd5b600c54600090600160a060020a031633148015906134865750600c54600160a060020a031615155b1561349057600080fd5b601154604080517fcedc7277000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251735f4928c421a53a9aa161d96886299ded68fb76a29163cedc7277916024808301926020929190829003018186803b1580156119ef57600080fd5b601154600160a060020a031681565b600054600160a060020a031681565b600c54600090600160a060020a0316331480159061354c5750600c54600160a060020a031615155b1561355657600080fd5b601154604080517feec5d076000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251735f4928c421a53a9aa161d96886299ded68fb76a29163eec5d076916024808301926020929190829003018186803b1580156119ef57600080fd5b60006010604051602001808280546001816001161561010002031660029004801561362e5780601f1061360c57610100808354040283529182019161362e565b820191906000526020600020905b81548152906001019060200180831161361a575b50509150506040516020818303038152906040526040518082805190602001908083835b602083106136715780518252601f199092019160209182019101613652565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020905090565b6040805160208082528183019092526060918291600091829184918082016104008038833901905050935060009250600091505b6020821015613787578582602081106136ec57fe5b1a60f860020a027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916600060f860020a0214151561377c5785826020811061373057fe5b1a60f860020a02848481518110151561374557fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001909201915b6001909101906136d7565b826040519080825280601f01601f1916602001820160405280156137b5578160200160208202803883390190505b509050600091505b8282101561382f5783828151811015156137d357fe5b90602001015160f860020a900460f860020a0281838151811015156137f457fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001909101906137bd565b95945050505050565b600c54606090600160a060020a031633148015906138605750600c54600160a060020a031615155b1561386a57600080fd5b601154604080517f81a73ad5000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251610f7191735f4928c421a53a9aa161d96886299ded68fb76a2916381a73ad591602480820192602092909190829003018186803b158015610f4057600080fd5b600080548190600160a060020a0316331480159061391357503360009081526004602052604090205460ff16155b1561391d57600080fd5b600c54600160a060020a031633148015906139425750600c54600160a060020a031615155b1561394c57600080fd5b6011546040805160e160020a635ac01573028152600160a060020a03909216600483015251735f4928c421a53a9aa161d96886299ded68fb76a29163b5802ae6916024808301926020929190829003018186803b1580156139ac57600080fd5b505af41580156139c0573d6000803e3d6000fd5b505050506040513d60208110156139d657600080fd5b5051600e54604080517f97304ced000000000000000000000000000000000000000000000000000000008152600481018790529051929350600160a060020a03909116916397304ced9160248082019260009290919082900301818387803b158015613a4157600080fd5b505af1158015613a55573d6000803e3d6000fd5b505050507f070aa035fe0a09f0d9305bdc2d7a5d93cd4733db3b1ff869b4a7033c9501909a83600e60009054906101000a9004600160a060020a0316600160a060020a0316637e1c0c096040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015613ace57600080fd5b505af1158015613ae2573d6000803e3d6000fd5b505050506040513d6020811015613af857600080fd5b5051604080519283526020830191909152818101849052519081900360600190a16040805184815290513091600091600080516020615cff8339815191529181900360200190a350600192915050565b6000600f604051602001808280546001816001161561010002031660029004801561362e5780601f1061360c57610100808354040283529182019161362e565b600754600090819060ff1615613b9d57600080fd5b3360009081526009602052604090205460ff1615613bba57600080fd5b600c54600160a060020a03163314801590613bdf5750600c54600160a060020a031615155b15613be957600080fd5b600160a060020a0383161515613bfe57600080fd5b600160a060020a03831660009081526009602052604090205460ff1615613c2457600080fd5b613c2d836114aa565b9050801515613c3f57600191506132b3565b601154604080517f4698da9d000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152918516602483015251735f4928c421a53a9aa161d96886299ded68fb76a291634698da9d916044808301926000929190829003018186803b158015613cbd57600080fd5b505af4158015613cd1573d6000803e3d6000fd5b5050600e54604080517f4cfe3e7f000000000000000000000000000000000000000000000000000000008152600160a060020a038881166004830152602482018790529151919092169350634cfe3e7f9250604480830192600092919082900301818387803b158015613d4357600080fd5b505af1158015613d57573d6000803e3d6000fd5b5050604080518481529051600160a060020a0387169350309250600080516020615cff8339815191529181900360200190a3604080518281529051600160a060020a038516917f39dfd9c15a87979822cf6b236d0974075578d5b822244050f3c876a6cd1d2055919081900360200190a250600192915050565b600c54600090600160a060020a03163314801590613df95750600c54600160a060020a031615155b15613e0357600080fd5b50600190565b6014805482908110611c9557fe5b601154604080517f576f7e31000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251600091735f4928c421a53a9aa161d96886299ded68fb76a29163576f7e3191602480820192602092909190829003018186803b1580156119ef57600080fd5b60075460009081908190819081908190819060ff1615613eb057600080fd5b3360009081526009602052604090205460ff1615613ecd57600080fd5b600c54600160a060020a03163314801590613ef25750600c54600160a060020a031615155b15613efc57600080fd5b6012547501000000000000000000000000000000000000000000900460ff1615613f2557600080fd5b601154604080517f336077c3000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015233602483015251735f4928c421a53a9aa161d96886299ded68fb76a29163336077c3916044808301926020929190829003018186803b158015613fa157600080fd5b505af4158015613fb5573d6000803e3d6000fd5b505050506040513d6020811015613fcb57600080fd5b50511515613fd857600080fd5b601154604080517fcedc7277000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251735f4928c421a53a9aa161d96886299ded68fb76a29163cedc7277916024808301926020929190829003018186803b15801561404e57600080fd5b505af4158015614062573d6000803e3d6000fd5b505050506040513d602081101561407857600080fd5b50516011546040805160e160020a635ac01573028152600160a060020a03909216600483015251919750735f4928c421a53a9aa161d96886299ded68fb76a29163b5802ae691602480820192602092909190829003018186803b1580156140de57600080fd5b505af41580156140f2573d6000803e3d6000fd5b505050506040513d602081101561410857600080fd5b505194506000341161411957600080fd5b6000861161412657600080fd5b6000851161413357600080fd5b614143348763ffffffff615bcd16565b93508461415e856141526122b3565b9063ffffffff615bc016565b111561416957600080fd5b614171612a62565b84111561417d57600080fd5b600e54604080517f70a082310000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a03909216916370a08231916024808201926020929091908290030181600087803b1580156141e357600080fd5b505af11580156141f7573d6000803e3d6000fd5b505050506040513d602081101561420d57600080fd5b5051601154604080517fddf9d613000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015233602483015251919350735f4928c421a53a9aa161d96886299ded68fb76a29163ddf9d61391604480820192602092909190829003018186803b15801561428f57600080fd5b505af41580156142a3573d6000803e3d6000fd5b505050506040513d60208110156142b957600080fd5b505160165490915015806142de57506016546142db838663ffffffff615bc016565b10155b15156142e957600080fd5b60008111156142fa5780925061439f565b601154604080517fec7c637d000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251735f4928c421a53a9aa161d96886299ded68fb76a29163ec7c637d916024808301926020929190829003018186803b15801561437057600080fd5b505af4158015614384573d6000803e3d6000fd5b505050506040513d602081101561439a57600080fd5b505192505b6000831180156143be57506143ba828563ffffffff615bc016565b8310155b15156143c957600080fd5b600e54604080517f4cfe3e7f000000000000000000000000000000000000000000000000000000008152336004820152602481018790529051600160a060020a0390921691634cfe3e7f9160448082019260009290919082900301818387803b15801561443557600080fd5b505af1158015614449573d6000803e3d6000fd5b5050604080518781529051339350309250600080516020615cff8339815191529181900360200190a3509195945050505050565b60075460009060ff161561449057600080fd5b3360009081526009602052604090205460ff16156144ad57600080fd5b600c54600160a060020a031633148015906144d25750600c54600160a060020a031615155b156144dc57600080fd5b60125460b060020a900460ff168061450357503360009081526013602052604090205460ff165b151561450e57600080fd5b6000821161451b57600080fd5b600160a060020a03831660009081526009602052604090205460ff161561454157600080fd5b600e54604080517fbeabacc8000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a038681166024830152604482018690529151919092169163beabacc891606480830192600092919082900301818387803b1580156145b557600080fd5b505af11580156145c9573d6000803e3d6000fd5b5050604080518581529051600160a060020a0387169350339250600080516020615cff8339815191529181900360200190a350600192915050565b60025490565b60046020526000908152604090205460ff1681565b600054600160a060020a0316331480159061464a57503360009081526004602052604090205460ff16155b1561465457600080fd5b600160a060020a038116151561466957600080fd5b600160a060020a0381166000908152600460209081526040808320805460ff19166001179055600690915290205460ff161515614704576002805460018082019092557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace018054600160a060020a031916600160a060020a0384169081179091556000908152600660205260409020805460ff191690911790555b604051600160a060020a038216907ffba24c034afca607a35e1f221b154b3f8e1f88c7924c8a0a06755b70708c44d890600090a250565b60096020526000908152604090205460ff1681565b600b54600160a060020a031681565b601154604080517f58c6bce8000000000000000000000000000000000000000000000000000000008152600160a060020a0390921660048301526024820183905251600091735f4928c421a53a9aa161d96886299ded68fb76a2916358c6bce891604480820192602092909190829003018186803b15801561119557600080fd5b600080548190600160a060020a0316331480159061480e57503360009081526004602052604090205460ff16155b1561481857600080fd5b600c54600160a060020a0316331480159061483d5750600c54600160a060020a031615155b1561484757600080fd5b600160a060020a038316151561485c57600080fd5b601154604080517f6ace6dc8000000000000000000000000000000000000000000000000000000008152600160a060020a03928316600482015291851660248301526001604483015251735f4928c421a53a9aa161d96886299ded68fb76a291636ace6dc8916064808301926000929190829003018186803b1580156148e157600080fd5b505af41580156148f5573d6000803e3d6000fd5b5050601154604080517fddf9d613000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152918716602483015251735f4928c421a53a9aa161d96886299ded68fb76a2935063ddf9d61392506044808301926020929190829003018186803b15801561497757600080fd5b505af415801561498b573d6000803e3d6000fd5b505050506040513d60208110156149a157600080fd5b50519050801515614a5157601154604080517fec7c637d000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251735f4928c421a53a9aa161d96886299ded68fb76a29163ec7c637d916024808301926020929190829003018186803b158015614a2257600080fd5b505af4158015614a36573d6000803e3d6000fd5b505050506040513d6020811015614a4c57600080fd5b505190505b604080518281529051600160a060020a038516917fcb3de9106aa8cc3efea54defa4b3ec342e8ae23607fd0255b1dcee4813f9f4bc919081900360200190a250600192915050565b601154604080517f336077c3000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152918316602483015251600091735f4928c421a53a9aa161d96886299ded68fb76a29163336077c391604480820192602092909190829003018186803b15801561119557600080fd5b6002805482908110611c9557fe5b600c54600160a060020a0316151590565b60008054600160a060020a03163314801590614b6657503360009081526004602052604090205460ff16155b15614b7057600080fd5b600c54600160a060020a03163314801590614b955750600c54600160a060020a031615155b15614b9f57600080fd5b614ba7612a62565b821115614bb357600080fd5b600160a060020a03831660009081526009602052604090205460ff1615614bd957600080fd5b600e54604080517f4cfe3e7f000000000000000000000000000000000000000000000000000000008152600160a060020a0386811660048301526024820186905291519190921691634cfe3e7f91604480830192600092919082900301818387803b158015614c4757600080fd5b505af1158015614c5b573d6000803e3d6000fd5b5050604080518581529051600160a060020a0387169350309250600080516020615cff8339815191529181900360200190a350600192915050565b60008054600160a060020a03163314801590614cc257503360009081526004602052604090205460ff16155b15614ccc57600080fd5b600c54600160a060020a03163314801590614cf15750600c54600160a060020a031615155b15614cfb57600080fd5b50601655600190565b601154604080517f96468249000000000000000000000000000000000000000000000000000000008152600160a060020a039092166004830152516000918291735f4928c421a53a9aa161d96886299ded68fb76a2916396468249916024808301926020929190829003018186803b158015614d7f57600080fd5b505af4158015614d93573d6000803e3d6000fd5b505050506040513d6020811015614da957600080fd5b50519050600160a060020a0381161515614dc257600080fd5b600054600160a060020a03163314801590614de6575033600160a060020a03821614155b15614df057600080fd5b604051339084156108fc029085906000818181858888f19350505050158015614e1d573d6000803e3d6000fd5b5060019392505050565b6010805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156122195780601f106121ee57610100808354040283529160200191612219565b6012547501000000000000000000000000000000000000000000900460ff1681565b600f805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156122195780601f106121ee57610100808354040283529160200191612219565b60075460009060ff1615614f1257600080fd5b3360009081526009602052604090205460ff1615614f2f57600080fd5b600c54600160a060020a03163314801590614f545750600c54600160a060020a031615155b15614f5e57600080fd5b601154604080517fe7092b41000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152336024820152918516604483015251615002918591612bf4918691735f4928c421a53a9aa161d96886299ded68fb76a29163e7092b41916064808301926020929190829003018186803b158015614fee57600080fd5b505af4158015612357573d6000803e3d6000fd5b9392505050565b60008054600160a060020a0316331480159061503557503360009081526004602052604090205460ff16155b1561503f57600080fd5b600c54600160a060020a031633148015906150645750600c54600160a060020a031615155b1561506e57600080fd5b600160a060020a038316151561508357600080fd5b601154604080517f4989b0b6000000000000000000000000000000000000000000000000000000008152600160a060020a03928316600482015291851660248301526044820184905251735f4928c421a53a9aa161d96886299ded68fb76a291634989b0b6916064808301926000929190829003018186803b15801561510857600080fd5b505af415801561511c573d6000803e3d6000fd5b50505050614e1d836147e0565b600c54600090600160a060020a031633148015906151515750600c54600160a060020a031615155b1561515b57600080fd5b601154604080517fe7092b41000000000000000000000000000000000000000000000000000000008152600160a060020a0392831660048201528583166024820152918416604483015251735f4928c421a53a9aa161d96886299ded68fb76a29163e7092b41916064808301926020929190829003018186803b1580156151e157600080fd5b505af41580156151f5573d6000803e3d6000fd5b505050506040513d602081101561520b57600080fd5b50519392505050565b60008054600160a060020a0316331480159061524057503360009081526004602052604090205460ff16155b1561524a57600080fd5b600c54600160a060020a0316331480159061526f5750600c54600160a060020a031615155b1561527957600080fd5b506012805482151560b060020a0276ff00000000000000000000000000000000000000000000199091161790556001919050565b601154604080517f27132be6000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251600091735f4928c421a53a9aa161d96886299ded68fb76a2916327132be691602480820192602092909190829003018186803b1580156119ef57600080fd5b600054600160a060020a0316331480159061535257503360009081526004602052604090205460ff16155b1561535c57600080fd5b600160a060020a0382166000908152600960209081526040808320805460ff1916851515179055600a90915290205460ff1615156153f8576008805460018082019092557ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3018054600160a060020a031916600160a060020a0385169081179091556000908152600a60205260409020805460ff191690911790555b6040805182151581529051600160a060020a038416917f48335238b4855f35377ed80f164e8c6f3c366e54ac00b96a6402d4a9814a03a5919081900360200190a25050565b60145490565b60136020526000908152604090205460ff1681565b600054600160a060020a0316331461546f57600080fd5b61547881615bf6565b50565b601154604080517fd97e38d6000000000000000000000000000000000000000000000000000000008152600160a060020a0390921660048301526024820183905251600091735f4928c421a53a9aa161d96886299ded68fb76a29163d97e38d691604480820192602092909190829003018186803b15801561119557600080fd5b60008054600160a060020a0316331480159061552857503360009081526004602052604090205460ff16155b1561553257600080fd5b600c54600160a060020a031633148015906155575750600c54600160a060020a031615155b1561556157600080fd5b600160a060020a038316151561557657600080fd5b600c8054600160a060020a031916600160a060020a03851617905560008211156155c957604080518381529051600160a060020a038516913091600080516020615cff8339815191529181900360200190a35b604051600160a060020a038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250600192915050565b60008054819081908190600160a060020a0316331480159061563857503360009081526004602052604090205460ff16155b1561564257600080fd5b600c54600160a060020a031633148015906156675750600c54600160a060020a031615155b1561567157600080fd5b6011546040805160e160020a635ac01573028152600160a060020a03909216600483015251735f4928c421a53a9aa161d96886299ded68fb76a29163b5802ae6916024808301926020929190829003018186803b1580156156d157600080fd5b505af41580156156e5573d6000803e3d6000fd5b505050506040513d60208110156156fb57600080fd5b50519250600160a060020a038a16151561571457600080fd5b600160a060020a038a1660009081526009602052604090205460ff161561573a57600080fd5b8686101561574757600080fd5b826157548a6141526122b3565b111561575f57600080fd5b615767612a62565b89111561577357600080fd5b429150871515615781578197505b615791888863ffffffff615bc016565b601154604080517fc4b9223f000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152918d166024830152604482018c9052606482018b90526084820183905260a4820189905287151560c483015251919250735f4928c421a53a9aa161d96886299ded68fb76a29163c4b9223f9160e480820192600092909190829003018186803b15801561583757600080fd5b505af415801561584b573d6000803e3d6000fd5b5050604080518b8152602081018590528082018a9052606081018d905288151560808201529051600160a060020a038e1693507f9c30dc484837afde1ded2722ef11ba4a8f599b3cf3205def0b668e9f5e33c79f92509081900360a00190a25060019998505050505050505050565b6000806000806000806000806000600c60009054906101000a9004600160a060020a0316600160a060020a031633600160a060020a0316141580156159095750600c54600160a060020a031615155b1561591357600080fd5b601154604080517fe16dd936000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152918c16602483015251735f4928c421a53a9aa161d96886299ded68fb76a29163e16dd9369160448083019260e0929190829003018186803b15801561599157600080fd5b505af41580156159a5573d6000803e3d6000fd5b505050506040513d60e08110156159bb57600080fd5b8101908080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190505050809750819850829950839c50849d50859e50869f5050505050505050601160009054906101000a9004600160a060020a0316600160a060020a0316735f4928c421a53a9aa161d96886299ded68fb76a263aa77f26c90918c6040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182600160a060020a0316600160a060020a031681526020019250505060206040518083038186803b158015615ac257600080fd5b505af4158015615ad6573d6000803e3d6000fd5b505050506040513d6020811015615aec57600080fd5b5051601154604080517fbca9adef000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152918d16602483015251919650735f4928c421a53a9aa161d96886299ded68fb76a29163bca9adef91604480820192602092909190829003018186803b158015615b7057600080fd5b505af4158015615b84573d6000803e3d6000fd5b505050506040513d6020811015615b9a57600080fd5b5051989a9799509597949693959193909250565b600082821115615bba57fe5b50900390565b8181018281101561110d57fe5b6000821515615bde5750600061110d565b50818102818382811515615bee57fe5b041461110d57fe5b600160a060020a0381161515615c0b57600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a360008054600160a060020a031916600160a060020a0392909216919091179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615ca757805160ff1916838001178555615cd4565b82800160010185558215615cd4579182015b82811115615cd4578251825591602001919060010190615cb9565b50615ce0929150615ce4565b5090565b610e9091905b80821115615ce05760008155600101615cea5600ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa165627a7a723058207c35ca72ac77a98c735fe3da0e9208f4e6afbcd86719711e675883cd5caa00f40029000000000000000000000000fc8deeb5cd80a3e8b8de353df9b5b09c71d3ef17000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000a63737453746f7261676500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b6c65646765722d43415244000000000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106103d95763ffffffff60e060020a6000350416630489882e81146103eb57806306fdde0314610412578063095ea7b31461049c578063115f2be2146104d457806313bac8f2146104f55780631726cbc81461058c5780631785f53c146105ad57806318160ddd146105d05780631a841b1b146105e55780632185810b146105fa578063222101d11461060f57806323b872dd146106245780632b28d2d01461064e578063313ce56714610663578063313f2a211461068e5780633886c957146106c25780633b0da260146106d757806341fbb050146106f8578063429b62e51461070d5780634610a4481461072e5780634902e4aa146107465780634f2d7ab514610767578063503720851461077c57806352fb05611461079157806354dd1da4146107b757806354fd4d50146107cc57806356597e65146107e15780635cb0c16f146107f65780635da01a5b1461080b57806360659a921461083b578063661884631461085057806366e3cb68146108745780636a420bbc146108955780636df006f3146108af5780636f75b00c146108c45780636ff968c3146108e557806370480275146108fa57806370a082311461091b578063715018a61461093c578063771eee16146109515780637b1039991461096b5780637db6cc1b14610980578063820e79ed146109985780638620410b146109ad57806388d7cd97146109c25780638da5cb5b146109d75780638df388c1146109ec5780638f1d5f7e14610a015780639201de5514610a1657806395d89b4114610a2e57806397304ced14610a435780639860811114610a5b57806399817b4714610a705780639ae066b014610a91578063a106e8c914610a99578063a4453a9614610ab1578063a6f2ae3a14610ac6578063a9059cbb14610ace578063abf7b06314610af2578063ad25cb4214610b07578063b3292ff014610b28578063b414d4b614610b49578063b719d03214610b6a578063b9447f7e14610b7f578063bbf8980314610b97578063c3437e0614610bb8578063c389439814610bd9578063c717823014610bf1578063c94e643c14610c06578063cb0b7b0314610c2a578063cedcd77014610c42578063cf1f3dd714610c5a578063d28dcdea14610c6f578063d73c277c14610c84578063d73dd62314610c99578063da14c72314610cbd578063dd62ed3e14610ce1578063df50afa414610d08578063e01bc60b14610d22578063e724529c14610d37578063e86d86ea14610d5d578063ec5da72114610d72578063f2fde38b14610d93578063f69f8a5c14610db4578063f6b2b33414610dcc578063fc13566d14610df0578063ffff6b0414610e22575b3480156103e557600080fd5b50600080fd5b3480156103f757600080fd5b50610400610e8c565b60408051918252519081900360200190f35b34801561041e57600080fd5b50610427610e93565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610461578181015183820152602001610449565b50505050905090810190601f16801561048e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156104a857600080fd5b506104c0600160a060020a0360043516602435610f76565b604080519115158252519081900360200190f35b3480156104e057600080fd5b50610400600160a060020a0360043516611113565b34801561050157600080fd5b506040805160206004803580820135601f81018490048402850184019095528484526104c094369492936024939284019190819084018382808284375050604080516020601f89358b018035918201839004830284018301909452808352979a9998810197919650918201945092508291508401838280828437509497506111c79650505050505050565b34801561059857600080fd5b50610400600160a060020a03600435166114aa565b3480156105b957600080fd5b506105ce600160a060020a036004351661155a565b005b3480156105dc57600080fd5b506104006115ed565b3480156105f157600080fd5b506104c06116a3565b34801561060657600080fd5b506104c0611937565b34801561061b57600080fd5b50610400611947565b34801561063057600080fd5b506104c0600160a060020a0360043581169060243516604435611a03565b34801561065a57600080fd5b50610400611c7c565b34801561066f57600080fd5b50610678611c82565b6040805160ff9092168252519081900360200190f35b34801561069a57600080fd5b506106a6600435611c87565b60408051600160a060020a039092168252519081900360200190f35b3480156106ce57600080fd5b506106a6611caf565b3480156106e357600080fd5b506104c0600160a060020a0360043516611cbe565b34801561070457600080fd5b506106a6611e14565b34801561071957600080fd5b506104c0600160a060020a0360043516611e8e565b34801561073a57600080fd5b506106a6600435611ea3565b34801561075257600080fd5b506105ce600160a060020a0360043516611f52565b34801561077357600080fd5b50610400611fe5565b34801561078857600080fd5b506104c0611feb565b34801561079d57600080fd5b506104c0600160a060020a0360043516602435151561200c565b3480156107c357600080fd5b506104c061212b565b3480156107d857600080fd5b50610427612193565b3480156107ed57600080fd5b50610400612221565b34801561080257600080fd5b506104006122b3565b34801561081757600080fd5b506104c0600435602435604435606435608435600160a060020a0360a4351661237b565b34801561084757600080fd5b50610400612a62565b34801561085c57600080fd5b506104c0600160a060020a0360043516602435612ab3565b34801561088057600080fd5b506104c0600160a060020a0360043516612c00565b3480156108a157600080fd5b506104c06004351515612e6c565b3480156108bb57600080fd5b506104c0612f76565b3480156108d057600080fd5b506104c0600160a060020a0360043516612f7f565b3480156108f157600080fd5b506106a661309e565b34801561090657600080fd5b506105ce600160a060020a03600435166130ad565b34801561092757600080fd5b50610400600160a060020a03600435166131c6565b34801561094857600080fd5b506105ce6132b9565b34801561095d57600080fd5b506105ce6004351515613318565b34801561097757600080fd5b506106a6613399565b34801561098c57600080fd5b506106a66004356133a8565b3480156109a457600080fd5b506104006133b6565b3480156109b957600080fd5b5061040061345e565b3480156109ce57600080fd5b506106a6613506565b3480156109e357600080fd5b506106a6613515565b3480156109f857600080fd5b50610400613524565b348015610a0d57600080fd5b506104006135cc565b348015610a2257600080fd5b506104276004356136a3565b348015610a3a57600080fd5b50610427613838565b348015610a4f57600080fd5b506104c06004356138e5565b348015610a6757600080fd5b50610400613b48565b348015610a7c57600080fd5b506104c0600160a060020a0360043516613b88565b6104c0613dd1565b348015610aa557600080fd5b506106a6600435613e09565b348015610abd57600080fd5b50610400613e17565b610400613e91565b348015610ada57600080fd5b506104c0600160a060020a036004351660243561447d565b348015610afe57600080fd5b50610400614604565b348015610b1357600080fd5b506104c0600160a060020a036004351661460a565b348015610b3457600080fd5b506105ce600160a060020a036004351661461f565b348015610b5557600080fd5b506104c0600160a060020a036004351661473b565b348015610b7657600080fd5b506106a6614750565b348015610b8b57600080fd5b506106a660043561475f565b348015610ba357600080fd5b506104c0600160a060020a03600435166147e0565b348015610bc457600080fd5b506104c0600160a060020a0360043516614a99565b348015610be557600080fd5b506106a6600435614b1b565b348015610bfd57600080fd5b506104c0614b29565b348015610c1257600080fd5b506104c0600160a060020a0360043516602435614b3a565b348015610c3657600080fd5b506104c0600435614c96565b348015610c4e57600080fd5b506104c0600435614d04565b348015610c6657600080fd5b50610427614e27565b348015610c7b57600080fd5b506104c0614e82565b348015610c9057600080fd5b50610427614ea4565b348015610ca557600080fd5b506104c0600160a060020a0360043516602435614eff565b348015610cc957600080fd5b506104c0600160a060020a0360043516602435615009565b348015610ced57600080fd5b50610400600160a060020a0360043581169060243516615129565b348015610d1457600080fd5b506104c06004351515615214565b348015610d2e57600080fd5b506104006152ad565b348015610d4357600080fd5b506105ce600160a060020a03600435166024351515615327565b348015610d6957600080fd5b5061040061543d565b348015610d7e57600080fd5b506104c0600160a060020a0360043516615443565b348015610d9f57600080fd5b506105ce600160a060020a0360043516615458565b348015610dc057600080fd5b506106a660043561547b565b348015610dd857600080fd5b506104c0600160a060020a03600435166024356154fc565b348015610dfc57600080fd5b506104c0600160a060020a036004351660243560443560643560843560a4351515615606565b348015610e2e57600080fd5b50610e43600160a060020a03600435166158ba565b60408051998a5260208a0198909852888801969096526060880194909452608087019290925260a086015260c085015260e0840152151561010083015251908190036101200190f35b6001545b90565b600c54606090600160a060020a03163314801590610ebb5750600c54600160a060020a031615155b15610ec557600080fd5b601154604080517f6f0fccab000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251610f7191735f4928c421a53a9aa161d96886299ded68fb76a291636f0fccab91602480820192602092909190829003018186803b158015610f4057600080fd5b505af4158015610f54573d6000803e3d6000fd5b505050506040513d6020811015610f6a57600080fd5b50516136a3565b905090565b60075460009060ff1615610f8957600080fd5b3360009081526009602052604090205460ff1615610fa657600080fd5b600c54600160a060020a03163314801590610fcb5750600c54600160a060020a031615155b15610fd557600080fd5b600160a060020a0383161515610fea57600080fd5b600160a060020a03831660009081526009602052604090205460ff161561101057600080fd5b33600160a060020a038416141561102657600080fd5b601154604080517fa7070373000000000000000000000000000000000000000000000000000000008152600160a060020a03928316600482015233602482015291851660448301526064820184905251735f4928c421a53a9aa161d96886299ded68fb76a29163a7070373916084808301926000929190829003018186803b1580156110b157600080fd5b505af41580156110c5573d6000803e3d6000fd5b5050604080518581529051600160a060020a03871693503392507f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259181900360200190a35060015b92915050565b601154604080517fddf9d613000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152918316602483015251600091735f4928c421a53a9aa161d96886299ded68fb76a29163ddf9d61391604480820192602092909190829003018186803b15801561119557600080fd5b505af41580156111a9573d6000803e3d6000fd5b505050506040513d60208110156111bf57600080fd5b505192915050565b6000805481908190600160a060020a031633148015906111f757503360009081526004602052604090205460ff16155b1561120157600080fd5b600c54600160a060020a031633148015906112265750600c54600160a060020a031615155b1561123057600080fd5b60075460ff16151561124157600080fd5b845161125490600f906020880190615c66565b508351611268906010906020870190615c66565b506112716116a3565b5060125460405160e160020a6328cf2aed028152602060048201908152601080546002600019600183161561010002019091160460248401819052600160a060020a039094169363519e55da939192918291604490910190849080156113185780601f106112ed57610100808354040283529160200191611318565b820191906000526020600020905b8154815290600101906020018083116112fb57829003601f168201915b505092505050602060405180830381600087803b15801561133857600080fd5b505af115801561134c573d6000803e3d6000fd5b505050506040513d602081101561136257600080fd5b505160125460405160e160020a6328cf2aed028152602060048201908152600f80546002600019600183161561010002019091160460248401819052949650600160a060020a039093169363519e55da939282916044909101908490801561140b5780601f106113e05761010080835404028352916020019161140b565b820191906000526020600020905b8154815290600101906020018083116113ee57829003601f168201915b505092505050602060405180830381600087803b15801561142b57600080fd5b505af115801561143f573d6000803e3d6000fd5b505050506040513d602081101561145557600080fd5b505160408051600160a060020a0380841682528516602082015281519293507f8e2c71dfeb156b7c7d03fa7cba1af111d058c575816f578cb3c2d8c6be99e0ca929081900390910190a1506001949350505050565b600c54600090600160a060020a031633148015906114d25750600c54600160a060020a031615155b156114dc57600080fd5b601154604080517f7243cfbb000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152918416602483015251735f4928c421a53a9aa161d96886299ded68fb76a291637243cfbb916044808301926020929190829003018186803b15801561119557600080fd5b600054600160a060020a0316331480159061158557503360009081526004602052604090205460ff16155b1561158f57600080fd5b600160a060020a03811615156115a457600080fd5b600160a060020a038116600081815260036020526040808220805460ff19169055517f753f40ca3312b2408759a67875b367955e7baa221daf08aa3d643d96202ac12b9190a250565b600c54600090600160a060020a031633148015906116155750600c54600160a060020a031615155b1561161f57600080fd5b600e60009054906101000a9004600160a060020a0316600160a060020a0316637e1c0c096040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561167257600080fd5b505af1158015611686573d6000803e3d6000fd5b505050506040513d602081101561169c57600080fd5b5051905090565b60008054600160a060020a031633148015906116cf57503360009081526004602052604090205460ff16155b156116d957600080fd5b600c54600160a060020a031633148015906116fe5750600c54600160a060020a031615155b1561170857600080fd5b60125460405160e160020a6328cf2aed0281526020600482019081526010805460026000196001831615610100020190911604602484018190526000948594600160a060020a039091169363519e55da939290918291604490910190849080156117b35780601f10611788576101008083540402835291602001916117b3565b820191906000526020600020905b81548152906001019060200180831161179657829003601f168201915b505092505050602060405180830381600087803b1580156117d357600080fd5b505af11580156117e7573d6000803e3d6000fd5b505050506040513d60208110156117fd57600080fd5b505160125460405160e160020a6328cf2aed028152602060048201908152600f80546002600019600183161561010002019091160460248401819052949650600160a060020a039093169363519e55da93928291604490910190849080156118a65780601f1061187b576101008083540402835291602001916118a6565b820191906000526020600020905b81548152906001019060200180831161188957829003601f168201915b505092505050602060405180830381600087803b1580156118c657600080fd5b505af11580156118da573d6000803e3d6000fd5b505050506040513d60208110156118f057600080fd5b5051600e8054600160a060020a03808616600160a060020a0319928316179092556011805492841692909116919091179055905061192e6001613318565b60019250505090565b60125460b060020a900460ff1681565b600c54600090600160a060020a0316331480159061196f5750600c54600160a060020a031615155b1561197957600080fd5b601154604080517f0b96406a000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251735f4928c421a53a9aa161d96886299ded68fb76a291630b96406a916024808301926020929190829003018186803b1580156119ef57600080fd5b505af4158015611686573d6000803e3d6000fd5b600754600090819060ff1615611a1857600080fd5b3360009081526009602052604090205460ff1615611a3557600080fd5b600c54600160a060020a03163314801590611a5a5750600c54600160a060020a031615155b15611a6457600080fd5b60125460b060020a900460ff161515611a7c57600080fd5b600160a060020a03851660009081526009602052604090205460ff1615611aa257600080fd5b600160a060020a03841660009081526009602052604090205460ff1615611ac857600080fd5b600160a060020a038516331415611ade57600080fd5b60008311611aeb57600080fd5b611af58533615129565b905082811015611b0457600080fd5b600e54604080517fbeabacc8000000000000000000000000000000000000000000000000000000008152600160a060020a0388811660048301528781166024830152604482018790529151919092169163beabacc891606480830192600092919082900301818387803b158015611b7a57600080fd5b505af1158015611b8e573d6000803e3d6000fd5b5050601154735f4928c421a53a9aa161d96886299ded68fb76a2925063a70703739150600160a060020a03168733611bcc868963ffffffff615bae16565b6040805160e060020a63ffffffff8816028152600160a060020a0395861660048201529385166024850152919093166044830152606482019290925290516084808301926000929190829003018186803b158015611c2957600080fd5b505af4158015611c3d573d6000803e3d6000fd5b5050604080518681529051600160a060020a03808916945089169250600080516020615cff8339815191529181900360200190a3506001949350505050565b60085490565b601281565b6001805482908110611c9557fe5b600091825260209091200154600160a060020a0316905081565b600e54600160a060020a031681565b60008054600160a060020a03163314801590611cea57503360009081526004602052604090205460ff16155b15611cf457600080fd5b600c54600160a060020a03163314801590611d195750600c54600160a060020a031615155b15611d2357600080fd5b600160a060020a0382161515611d3857600080fd5b601154604080517f3613b781000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152918416602483015251735f4928c421a53a9aa161d96886299ded68fb76a291633613b781916044808301926000929190829003018186803b158015611db657600080fd5b505af4158015611dca573d6000803e3d6000fd5b50505050611dd782613b88565b50604051600160a060020a038316907fe8a24516e1d3bae0c4742f4e5ded148733d2193d648d57d54bbec9c20e4b444990600090a2506001919050565b601154604080517f96468249000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251600091735f4928c421a53a9aa161d96886299ded68fb76a291639646824991602480820192602092909190829003018186803b1580156119ef57600080fd5b60036020526000908152604090205460ff1681565b600c54600090600160a060020a03163314801590611ecb5750600c54600160a060020a031615155b15611ed557600080fd5b601154604080517f52bafbfa000000000000000000000000000000000000000000000000000000008152600160a060020a0390921660048301526024820184905251735f4928c421a53a9aa161d96886299ded68fb76a2916352bafbfa916044808301926020929190829003018186803b15801561119557600080fd5b600054600160a060020a03163314801590611f7d57503360009081526004602052604090205460ff16155b15611f8757600080fd5b600160a060020a0381161515611f9c57600080fd5b600160a060020a038116600081815260046020526040808220805460ff19169055517f1aaaaf7609619e631f47eb3546f9fdd8c61b1af2175988a0ddb9a06680c3b9ed9190a250565b60165481565b60125474010000000000000000000000000000000000000000900460ff1681565b60008054600160a060020a0316331480159061203857503360009081526004602052604090205460ff16155b1561204257600080fd5b600c54600160a060020a031633148015906120675750600c54600160a060020a031615155b1561207157600080fd5b600160a060020a038316151561208657600080fd5b600160a060020a0383166000908152601360209081526040808320805460ff1916861515179055601590915290205460ff161515612122576014805460018082019092557fce6d7b5282bd9a3661ae061feed1dbda4e52ab073b1f9285be6e155d9c38d4ec018054600160a060020a031916600160a060020a0386169081179091556000908152601560205260409020805460ff191690911790555b50600192915050565b60075460009060ff161561213e57600080fd5b3360009081526009602052604090205460ff161561215b57600080fd5b600c54600160a060020a031633148015906121805750600c54600160a060020a031615155b1561218a57600080fd5b610f7133613b88565b600d805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156122195780601f106121ee57610100808354040283529160200191612219565b820191906000526020600020905b8154815290600101906020018083116121fc57829003601f168201915b505050505081565b600c54600090600160a060020a031633148015906122495750600c54600160a060020a031615155b1561225357600080fd5b6011546040805160e160020a635ac01573028152600160a060020a03909216600483015251735f4928c421a53a9aa161d96886299ded68fb76a29163b5802ae6916024808301926020929190829003018186803b1580156119ef57600080fd5b600c54600090600160a060020a031633148015906122db5750600c54600160a060020a031615155b156122e557600080fd5b610f716122f0613524565b600e60009054906101000a9004600160a060020a0316600160a060020a0316635cb0c16f6040518163ffffffff1660e060020a028152600401602060405180830381600087803b15801561234357600080fd5b505af1158015612357573d6000803e3d6000fd5b505050506040513d602081101561236d57600080fd5b50519063ffffffff615bc016565b600080548190600160a060020a031633148015906123a957503360009081526004602052604090205460ff16155b156123b357600080fd5b60125460405160e160020a6328cf2aed0281526020600482019081526010805460026000196001831615610100020190911604602484018190526000948594600160a060020a039091169363519e55da9392909182916044909101908490801561245e5780601f106124335761010080835404028352916020019161245e565b820191906000526020600020905b81548152906001019060200180831161244157829003601f168201915b505092505050602060405180830381600087803b15801561247e57600080fd5b505af1158015612492573d6000803e3d6000fd5b505050506040513d60208110156124a857600080fd5b505160125460405160e160020a6328cf2aed028152602060048201908152600f80546002600019600183161561010002019091160460248401819052949650600160a060020a039093169363519e55da93928291604490910190849080156125515780601f1061252657610100808354040283529160200191612551565b820191906000526020600020905b81548152906001019060200180831161253457829003601f168201915b505092505050602060405180830381600087803b15801561257157600080fd5b505af1158015612585573d6000803e3d6000fd5b505050506040513d602081101561259b57600080fd5b5051600e8054600160a060020a03808616600160a060020a0319928316179092556011805483851692169190911790819055604080517fcedc72770000000000000000000000000000000000000000000000000000000081529190921660048201529051919250735f4928c421a53a9aa161d96886299ded68fb76a29163cedc727791602480820192602092909190829003018186803b15801561263e57600080fd5b505af4158015612652573d6000803e3d6000fd5b505050506040513d602081101561266857600080fd5b5051925060008311801561267c5750878314155b156126925760075460ff16151561269257600080fd5b601154604080517f9c473bb2000000000000000000000000000000000000000000000000000000008152600160a060020a039092166004830152602482018c905251735f4928c421a53a9aa161d96886299ded68fb76a291639c473bb2916044808301926000929190829003018186803b15801561270f57600080fd5b505af4158015612723573d6000803e3d6000fd5b5050601154604080517fe6e623d5000000000000000000000000000000000000000000000000000000008152600160a060020a039092166004830152602482018d905251735f4928c421a53a9aa161d96886299ded68fb76a2935063e6e623d592506044808301926000929190829003018186803b1580156127a457600080fd5b505af41580156127b8573d6000803e3d6000fd5b5050601154604080517f1112b124000000000000000000000000000000000000000000000000000000008152600160a060020a039092166004830152602482018c905251735f4928c421a53a9aa161d96886299ded68fb76a29350631112b12492506044808301926000929190829003018186803b15801561283957600080fd5b505af415801561284d573d6000803e3d6000fd5b5050601154604080517fcd54c54e000000000000000000000000000000000000000000000000000000008152600160a060020a039092166004830152602482018b905251735f4928c421a53a9aa161d96886299ded68fb76a2935063cd54c54e92506044808301926000929190829003018186803b1580156128ce57600080fd5b505af41580156128e2573d6000803e3d6000fd5b5050601154604080517f05bf779f000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152918916602483015251735f4928c421a53a9aa161d96886299ded68fb76a293506305bf779f92506044808301926000929190829003018186803b15801561296457600080fd5b505af4158015612978573d6000803e3d6000fd5b5050601154604080517fdbafdbb6000000000000000000000000000000000000000000000000000000008152600160a060020a039092166004830152602482018a905251735f4928c421a53a9aa161d96886299ded68fb76a2935063dbafdbb692506044808301926000929190829003018186803b1580156129f957600080fd5b505af4158015612a0d573d6000803e3d6000fd5b5050604080518b8152602081018b90528082018a905290517f9d1a3ea811a60a1b2c08f8e30a09832514a3ec19ba354d73d8fe12ad66591cec9350908190036060019150a15060019998505050505050505050565b600c54600090600160a060020a03163314801590612a8a5750600c54600160a060020a031615155b15612a9457600080fd5b610f71612a9f6122b3565b612aa76115ed565b9063ffffffff615bae16565b600754600090819060ff1615612ac857600080fd5b3360009081526009602052604090205460ff1615612ae557600080fd5b600c54600160a060020a03163314801590612b0a5750600c54600160a060020a031615155b15612b1457600080fd5b601154604080517fe7092b41000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152336024820152918616604483015251735f4928c421a53a9aa161d96886299ded68fb76a29163e7092b41916064808301926020929190829003018186803b158015612b9857600080fd5b505af4158015612bac573d6000803e3d6000fd5b505050506040513d6020811015612bc257600080fd5b5051905080831115612be057612bd9846000610f76565b9150612bf9565b612bd984612bf4838663ffffffff615bae16565b610f76565b5092915050565b60008054600160a060020a03163314801590612c2c57503360009081526004602052604090205460ff16155b15612c3657600080fd5b600160a060020a0382161515612c4b57600080fd5b600b8054600160a060020a031916600160a060020a0384169081179091556040517f75c09cedaf6c35dc577b0fd0a8c77c569c84be03eae895084c7c60788eac7d6490600090a26000600160a060020a031682600160a060020a031663b719d0326040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015612cdb57600080fd5b505af1158015612cef573d6000803e3d6000fd5b505050506040513d6020811015612d0557600080fd5b5051600160a060020a031614612e3d5781600160a060020a031663503720856040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015612d5357600080fd5b505af1158015612d67573d6000803e3d6000fd5b505050506040513d6020811015612d7d57600080fd5b505115612e3857604080517f70a08231000000000000000000000000000000000000000000000000000000008152600160a060020a038416600482018190529151309291600080516020615cff8339815191529183916370a082319160248083019260209291908290030181600087803b158015612dfa57600080fd5b505af1158015612e0e573d6000803e3d6000fd5b505050506040513d6020811015612e2457600080fd5b505160408051918252519081900360200190a35b612e64565b6040805160008152905130918291600080516020615cff8339815191529181900360200190a35b506001919050565b60008054600160a060020a03163314801590612e9857503360009081526004602052604090205460ff16155b15612ea257600080fd5b600c54600160a060020a03163314801590612ec75750600c54600160a060020a031615155b15612ed157600080fd5b601280548315801575010000000000000000000000000000000000000000000275ff0000000000000000000000000000000000000000001990921691909117909155612f45576040517ff5eced797ccd723743102a9d898a1372f6bd7a0206c4facf99081b9471f5727290600090a1612e64565b6040517fd20fe4b54e307993c74930d195aa389bf91e188918e31ad1da29aad5a748a4d390600090a1506001919050565b60075460ff1681565b60008054600160a060020a03163314801590612fab57503360009081526004602052604090205460ff16155b15612fb557600080fd5b600c54600160a060020a03163314801590612fda5750600c54600160a060020a031615155b15612fe457600080fd5b600160a060020a0382161515612ff957600080fd5b601154604080517f6ace6dc8000000000000000000000000000000000000000000000000000000008152600160a060020a03928316600482015291841660248301526000604483018190529051735f4928c421a53a9aa161d96886299ded68fb76a292636ace6dc8926064808301939192829003018186803b15801561307e57600080fd5b505af4158015613092573d6000803e3d6000fd5b50600195945050505050565b600c54600160a060020a031681565b600054600160a060020a031633148015906130d857503360009081526004602052604090205460ff16155b156130e257600080fd5b600160a060020a03811615156130f757600080fd5b600160a060020a0381166000908152600360209081526040808320805460ff19166001179055600590915290205460ff16151561318f576001805480820182557fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6018054600160a060020a031916600160a060020a0384169081179091556000908152600560205260409020805460ff191690911790555b604051600160a060020a038216907fad6de4452a631e641cb59902236607946ce9272b9b981f2f80e8d129cb9084ba90600090a250565b600c546000908190600160a060020a031633148015906131f05750600c54600160a060020a031615155b156131fa57600080fd5b5030600160a060020a03831681141561321c57613215612a62565b91506132b3565b600e54604080517f70a08231000000000000000000000000000000000000000000000000000000008152600160a060020a038681166004830152915191909216916370a082319160248083019260209291908290030181600087803b15801561328457600080fd5b505af1158015613298573d6000803e3d6000fd5b505050506040513d60208110156132ae57600080fd5b505191505b50919050565b600054600160a060020a031633146132d057600080fd5b60008054604051600160a060020a03909116917ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482091a260008054600160a060020a0319169055565b600054600160a060020a0316331480159061334357503360009081526004602052604090205460ff16155b1561334d57600080fd5b6007805460ff191682151517908190556040805160ff90921615158252517f1623ff1a4138a65cb1f44d1a94c034f7dd8c1e826fefb1f27f0898580601e68d916020908290030190a150565b601254600160a060020a031681565b6008805482908110611c9557fe5b600c54600090600160a060020a031633148015906133de5750600c54600160a060020a031615155b156133e857600080fd5b601154604080517fec7c637d000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251735f4928c421a53a9aa161d96886299ded68fb76a29163ec7c637d916024808301926020929190829003018186803b1580156119ef57600080fd5b600c54600090600160a060020a031633148015906134865750600c54600160a060020a031615155b1561349057600080fd5b601154604080517fcedc7277000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251735f4928c421a53a9aa161d96886299ded68fb76a29163cedc7277916024808301926020929190829003018186803b1580156119ef57600080fd5b601154600160a060020a031681565b600054600160a060020a031681565b600c54600090600160a060020a0316331480159061354c5750600c54600160a060020a031615155b1561355657600080fd5b601154604080517feec5d076000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251735f4928c421a53a9aa161d96886299ded68fb76a29163eec5d076916024808301926020929190829003018186803b1580156119ef57600080fd5b60006010604051602001808280546001816001161561010002031660029004801561362e5780601f1061360c57610100808354040283529182019161362e565b820191906000526020600020905b81548152906001019060200180831161361a575b50509150506040516020818303038152906040526040518082805190602001908083835b602083106136715780518252601f199092019160209182019101613652565b6001836020036101000a0380198251168184511680821785525050505050509050019150506040518091039020905090565b6040805160208082528183019092526060918291600091829184918082016104008038833901905050935060009250600091505b6020821015613787578582602081106136ec57fe5b1a60f860020a027effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916600060f860020a0214151561377c5785826020811061373057fe5b1a60f860020a02848481518110151561374557fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001909201915b6001909101906136d7565b826040519080825280601f01601f1916602001820160405280156137b5578160200160208202803883390190505b509050600091505b8282101561382f5783828151811015156137d357fe5b90602001015160f860020a900460f860020a0281838151811015156137f457fe5b9060200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506001909101906137bd565b95945050505050565b600c54606090600160a060020a031633148015906138605750600c54600160a060020a031615155b1561386a57600080fd5b601154604080517f81a73ad5000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251610f7191735f4928c421a53a9aa161d96886299ded68fb76a2916381a73ad591602480820192602092909190829003018186803b158015610f4057600080fd5b600080548190600160a060020a0316331480159061391357503360009081526004602052604090205460ff16155b1561391d57600080fd5b600c54600160a060020a031633148015906139425750600c54600160a060020a031615155b1561394c57600080fd5b6011546040805160e160020a635ac01573028152600160a060020a03909216600483015251735f4928c421a53a9aa161d96886299ded68fb76a29163b5802ae6916024808301926020929190829003018186803b1580156139ac57600080fd5b505af41580156139c0573d6000803e3d6000fd5b505050506040513d60208110156139d657600080fd5b5051600e54604080517f97304ced000000000000000000000000000000000000000000000000000000008152600481018790529051929350600160a060020a03909116916397304ced9160248082019260009290919082900301818387803b158015613a4157600080fd5b505af1158015613a55573d6000803e3d6000fd5b505050507f070aa035fe0a09f0d9305bdc2d7a5d93cd4733db3b1ff869b4a7033c9501909a83600e60009054906101000a9004600160a060020a0316600160a060020a0316637e1c0c096040518163ffffffff1660e060020a028152600401602060405180830381600087803b158015613ace57600080fd5b505af1158015613ae2573d6000803e3d6000fd5b505050506040513d6020811015613af857600080fd5b5051604080519283526020830191909152818101849052519081900360600190a16040805184815290513091600091600080516020615cff8339815191529181900360200190a350600192915050565b6000600f604051602001808280546001816001161561010002031660029004801561362e5780601f1061360c57610100808354040283529182019161362e565b600754600090819060ff1615613b9d57600080fd5b3360009081526009602052604090205460ff1615613bba57600080fd5b600c54600160a060020a03163314801590613bdf5750600c54600160a060020a031615155b15613be957600080fd5b600160a060020a0383161515613bfe57600080fd5b600160a060020a03831660009081526009602052604090205460ff1615613c2457600080fd5b613c2d836114aa565b9050801515613c3f57600191506132b3565b601154604080517f4698da9d000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152918516602483015251735f4928c421a53a9aa161d96886299ded68fb76a291634698da9d916044808301926000929190829003018186803b158015613cbd57600080fd5b505af4158015613cd1573d6000803e3d6000fd5b5050600e54604080517f4cfe3e7f000000000000000000000000000000000000000000000000000000008152600160a060020a038881166004830152602482018790529151919092169350634cfe3e7f9250604480830192600092919082900301818387803b158015613d4357600080fd5b505af1158015613d57573d6000803e3d6000fd5b5050604080518481529051600160a060020a0387169350309250600080516020615cff8339815191529181900360200190a3604080518281529051600160a060020a038516917f39dfd9c15a87979822cf6b236d0974075578d5b822244050f3c876a6cd1d2055919081900360200190a250600192915050565b600c54600090600160a060020a03163314801590613df95750600c54600160a060020a031615155b15613e0357600080fd5b50600190565b6014805482908110611c9557fe5b601154604080517f576f7e31000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251600091735f4928c421a53a9aa161d96886299ded68fb76a29163576f7e3191602480820192602092909190829003018186803b1580156119ef57600080fd5b60075460009081908190819081908190819060ff1615613eb057600080fd5b3360009081526009602052604090205460ff1615613ecd57600080fd5b600c54600160a060020a03163314801590613ef25750600c54600160a060020a031615155b15613efc57600080fd5b6012547501000000000000000000000000000000000000000000900460ff1615613f2557600080fd5b601154604080517f336077c3000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015233602483015251735f4928c421a53a9aa161d96886299ded68fb76a29163336077c3916044808301926020929190829003018186803b158015613fa157600080fd5b505af4158015613fb5573d6000803e3d6000fd5b505050506040513d6020811015613fcb57600080fd5b50511515613fd857600080fd5b601154604080517fcedc7277000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251735f4928c421a53a9aa161d96886299ded68fb76a29163cedc7277916024808301926020929190829003018186803b15801561404e57600080fd5b505af4158015614062573d6000803e3d6000fd5b505050506040513d602081101561407857600080fd5b50516011546040805160e160020a635ac01573028152600160a060020a03909216600483015251919750735f4928c421a53a9aa161d96886299ded68fb76a29163b5802ae691602480820192602092909190829003018186803b1580156140de57600080fd5b505af41580156140f2573d6000803e3d6000fd5b505050506040513d602081101561410857600080fd5b505194506000341161411957600080fd5b6000861161412657600080fd5b6000851161413357600080fd5b614143348763ffffffff615bcd16565b93508461415e856141526122b3565b9063ffffffff615bc016565b111561416957600080fd5b614171612a62565b84111561417d57600080fd5b600e54604080517f70a082310000000000000000000000000000000000000000000000000000000081523360048201529051600160a060020a03909216916370a08231916024808201926020929091908290030181600087803b1580156141e357600080fd5b505af11580156141f7573d6000803e3d6000fd5b505050506040513d602081101561420d57600080fd5b5051601154604080517fddf9d613000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015233602483015251919350735f4928c421a53a9aa161d96886299ded68fb76a29163ddf9d61391604480820192602092909190829003018186803b15801561428f57600080fd5b505af41580156142a3573d6000803e3d6000fd5b505050506040513d60208110156142b957600080fd5b505160165490915015806142de57506016546142db838663ffffffff615bc016565b10155b15156142e957600080fd5b60008111156142fa5780925061439f565b601154604080517fec7c637d000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251735f4928c421a53a9aa161d96886299ded68fb76a29163ec7c637d916024808301926020929190829003018186803b15801561437057600080fd5b505af4158015614384573d6000803e3d6000fd5b505050506040513d602081101561439a57600080fd5b505192505b6000831180156143be57506143ba828563ffffffff615bc016565b8310155b15156143c957600080fd5b600e54604080517f4cfe3e7f000000000000000000000000000000000000000000000000000000008152336004820152602481018790529051600160a060020a0390921691634cfe3e7f9160448082019260009290919082900301818387803b15801561443557600080fd5b505af1158015614449573d6000803e3d6000fd5b5050604080518781529051339350309250600080516020615cff8339815191529181900360200190a3509195945050505050565b60075460009060ff161561449057600080fd5b3360009081526009602052604090205460ff16156144ad57600080fd5b600c54600160a060020a031633148015906144d25750600c54600160a060020a031615155b156144dc57600080fd5b60125460b060020a900460ff168061450357503360009081526013602052604090205460ff165b151561450e57600080fd5b6000821161451b57600080fd5b600160a060020a03831660009081526009602052604090205460ff161561454157600080fd5b600e54604080517fbeabacc8000000000000000000000000000000000000000000000000000000008152336004820152600160a060020a038681166024830152604482018690529151919092169163beabacc891606480830192600092919082900301818387803b1580156145b557600080fd5b505af11580156145c9573d6000803e3d6000fd5b5050604080518581529051600160a060020a0387169350339250600080516020615cff8339815191529181900360200190a350600192915050565b60025490565b60046020526000908152604090205460ff1681565b600054600160a060020a0316331480159061464a57503360009081526004602052604090205460ff16155b1561465457600080fd5b600160a060020a038116151561466957600080fd5b600160a060020a0381166000908152600460209081526040808320805460ff19166001179055600690915290205460ff161515614704576002805460018082019092557f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace018054600160a060020a031916600160a060020a0384169081179091556000908152600660205260409020805460ff191690911790555b604051600160a060020a038216907ffba24c034afca607a35e1f221b154b3f8e1f88c7924c8a0a06755b70708c44d890600090a250565b60096020526000908152604090205460ff1681565b600b54600160a060020a031681565b601154604080517f58c6bce8000000000000000000000000000000000000000000000000000000008152600160a060020a0390921660048301526024820183905251600091735f4928c421a53a9aa161d96886299ded68fb76a2916358c6bce891604480820192602092909190829003018186803b15801561119557600080fd5b600080548190600160a060020a0316331480159061480e57503360009081526004602052604090205460ff16155b1561481857600080fd5b600c54600160a060020a0316331480159061483d5750600c54600160a060020a031615155b1561484757600080fd5b600160a060020a038316151561485c57600080fd5b601154604080517f6ace6dc8000000000000000000000000000000000000000000000000000000008152600160a060020a03928316600482015291851660248301526001604483015251735f4928c421a53a9aa161d96886299ded68fb76a291636ace6dc8916064808301926000929190829003018186803b1580156148e157600080fd5b505af41580156148f5573d6000803e3d6000fd5b5050601154604080517fddf9d613000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152918716602483015251735f4928c421a53a9aa161d96886299ded68fb76a2935063ddf9d61392506044808301926020929190829003018186803b15801561497757600080fd5b505af415801561498b573d6000803e3d6000fd5b505050506040513d60208110156149a157600080fd5b50519050801515614a5157601154604080517fec7c637d000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251735f4928c421a53a9aa161d96886299ded68fb76a29163ec7c637d916024808301926020929190829003018186803b158015614a2257600080fd5b505af4158015614a36573d6000803e3d6000fd5b505050506040513d6020811015614a4c57600080fd5b505190505b604080518281529051600160a060020a038516917fcb3de9106aa8cc3efea54defa4b3ec342e8ae23607fd0255b1dcee4813f9f4bc919081900360200190a250600192915050565b601154604080517f336077c3000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152918316602483015251600091735f4928c421a53a9aa161d96886299ded68fb76a29163336077c391604480820192602092909190829003018186803b15801561119557600080fd5b6002805482908110611c9557fe5b600c54600160a060020a0316151590565b60008054600160a060020a03163314801590614b6657503360009081526004602052604090205460ff16155b15614b7057600080fd5b600c54600160a060020a03163314801590614b955750600c54600160a060020a031615155b15614b9f57600080fd5b614ba7612a62565b821115614bb357600080fd5b600160a060020a03831660009081526009602052604090205460ff1615614bd957600080fd5b600e54604080517f4cfe3e7f000000000000000000000000000000000000000000000000000000008152600160a060020a0386811660048301526024820186905291519190921691634cfe3e7f91604480830192600092919082900301818387803b158015614c4757600080fd5b505af1158015614c5b573d6000803e3d6000fd5b5050604080518581529051600160a060020a0387169350309250600080516020615cff8339815191529181900360200190a350600192915050565b60008054600160a060020a03163314801590614cc257503360009081526004602052604090205460ff16155b15614ccc57600080fd5b600c54600160a060020a03163314801590614cf15750600c54600160a060020a031615155b15614cfb57600080fd5b50601655600190565b601154604080517f96468249000000000000000000000000000000000000000000000000000000008152600160a060020a039092166004830152516000918291735f4928c421a53a9aa161d96886299ded68fb76a2916396468249916024808301926020929190829003018186803b158015614d7f57600080fd5b505af4158015614d93573d6000803e3d6000fd5b505050506040513d6020811015614da957600080fd5b50519050600160a060020a0381161515614dc257600080fd5b600054600160a060020a03163314801590614de6575033600160a060020a03821614155b15614df057600080fd5b604051339084156108fc029085906000818181858888f19350505050158015614e1d573d6000803e3d6000fd5b5060019392505050565b6010805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156122195780601f106121ee57610100808354040283529160200191612219565b6012547501000000000000000000000000000000000000000000900460ff1681565b600f805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156122195780601f106121ee57610100808354040283529160200191612219565b60075460009060ff1615614f1257600080fd5b3360009081526009602052604090205460ff1615614f2f57600080fd5b600c54600160a060020a03163314801590614f545750600c54600160a060020a031615155b15614f5e57600080fd5b601154604080517fe7092b41000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152336024820152918516604483015251615002918591612bf4918691735f4928c421a53a9aa161d96886299ded68fb76a29163e7092b41916064808301926020929190829003018186803b158015614fee57600080fd5b505af4158015612357573d6000803e3d6000fd5b9392505050565b60008054600160a060020a0316331480159061503557503360009081526004602052604090205460ff16155b1561503f57600080fd5b600c54600160a060020a031633148015906150645750600c54600160a060020a031615155b1561506e57600080fd5b600160a060020a038316151561508357600080fd5b601154604080517f4989b0b6000000000000000000000000000000000000000000000000000000008152600160a060020a03928316600482015291851660248301526044820184905251735f4928c421a53a9aa161d96886299ded68fb76a291634989b0b6916064808301926000929190829003018186803b15801561510857600080fd5b505af415801561511c573d6000803e3d6000fd5b50505050614e1d836147e0565b600c54600090600160a060020a031633148015906151515750600c54600160a060020a031615155b1561515b57600080fd5b601154604080517fe7092b41000000000000000000000000000000000000000000000000000000008152600160a060020a0392831660048201528583166024820152918416604483015251735f4928c421a53a9aa161d96886299ded68fb76a29163e7092b41916064808301926020929190829003018186803b1580156151e157600080fd5b505af41580156151f5573d6000803e3d6000fd5b505050506040513d602081101561520b57600080fd5b50519392505050565b60008054600160a060020a0316331480159061524057503360009081526004602052604090205460ff16155b1561524a57600080fd5b600c54600160a060020a0316331480159061526f5750600c54600160a060020a031615155b1561527957600080fd5b506012805482151560b060020a0276ff00000000000000000000000000000000000000000000199091161790556001919050565b601154604080517f27132be6000000000000000000000000000000000000000000000000000000008152600160a060020a03909216600483015251600091735f4928c421a53a9aa161d96886299ded68fb76a2916327132be691602480820192602092909190829003018186803b1580156119ef57600080fd5b600054600160a060020a0316331480159061535257503360009081526004602052604090205460ff16155b1561535c57600080fd5b600160a060020a0382166000908152600960209081526040808320805460ff1916851515179055600a90915290205460ff1615156153f8576008805460018082019092557ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3018054600160a060020a031916600160a060020a0385169081179091556000908152600a60205260409020805460ff191690911790555b6040805182151581529051600160a060020a038416917f48335238b4855f35377ed80f164e8c6f3c366e54ac00b96a6402d4a9814a03a5919081900360200190a25050565b60145490565b60136020526000908152604090205460ff1681565b600054600160a060020a0316331461546f57600080fd5b61547881615bf6565b50565b601154604080517fd97e38d6000000000000000000000000000000000000000000000000000000008152600160a060020a0390921660048301526024820183905251600091735f4928c421a53a9aa161d96886299ded68fb76a29163d97e38d691604480820192602092909190829003018186803b15801561119557600080fd5b60008054600160a060020a0316331480159061552857503360009081526004602052604090205460ff16155b1561553257600080fd5b600c54600160a060020a031633148015906155575750600c54600160a060020a031615155b1561556157600080fd5b600160a060020a038316151561557657600080fd5b600c8054600160a060020a031916600160a060020a03851617905560008211156155c957604080518381529051600160a060020a038516913091600080516020615cff8339815191529181900360200190a35b604051600160a060020a038416907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250600192915050565b60008054819081908190600160a060020a0316331480159061563857503360009081526004602052604090205460ff16155b1561564257600080fd5b600c54600160a060020a031633148015906156675750600c54600160a060020a031615155b1561567157600080fd5b6011546040805160e160020a635ac01573028152600160a060020a03909216600483015251735f4928c421a53a9aa161d96886299ded68fb76a29163b5802ae6916024808301926020929190829003018186803b1580156156d157600080fd5b505af41580156156e5573d6000803e3d6000fd5b505050506040513d60208110156156fb57600080fd5b50519250600160a060020a038a16151561571457600080fd5b600160a060020a038a1660009081526009602052604090205460ff161561573a57600080fd5b8686101561574757600080fd5b826157548a6141526122b3565b111561575f57600080fd5b615767612a62565b89111561577357600080fd5b429150871515615781578197505b615791888863ffffffff615bc016565b601154604080517fc4b9223f000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152918d166024830152604482018c9052606482018b90526084820183905260a4820189905287151560c483015251919250735f4928c421a53a9aa161d96886299ded68fb76a29163c4b9223f9160e480820192600092909190829003018186803b15801561583757600080fd5b505af415801561584b573d6000803e3d6000fd5b5050604080518b8152602081018590528082018a9052606081018d905288151560808201529051600160a060020a038e1693507f9c30dc484837afde1ded2722ef11ba4a8f599b3cf3205def0b668e9f5e33c79f92509081900360a00190a25060019998505050505050505050565b6000806000806000806000806000600c60009054906101000a9004600160a060020a0316600160a060020a031633600160a060020a0316141580156159095750600c54600160a060020a031615155b1561591357600080fd5b601154604080517fe16dd936000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152918c16602483015251735f4928c421a53a9aa161d96886299ded68fb76a29163e16dd9369160448083019260e0929190829003018186803b15801561599157600080fd5b505af41580156159a5573d6000803e3d6000fd5b505050506040513d60e08110156159bb57600080fd5b8101908080519060200190929190805190602001909291908051906020019092919080519060200190929190805190602001909291908051906020019092919080519060200190929190505050809750819850829950839c50849d50859e50869f5050505050505050601160009054906101000a9004600160a060020a0316600160a060020a0316735f4928c421a53a9aa161d96886299ded68fb76a263aa77f26c90918c6040518363ffffffff1660e060020a0281526004018083600160a060020a0316600160a060020a0316815260200182600160a060020a0316600160a060020a031681526020019250505060206040518083038186803b158015615ac257600080fd5b505af4158015615ad6573d6000803e3d6000fd5b505050506040513d6020811015615aec57600080fd5b5051601154604080517fbca9adef000000000000000000000000000000000000000000000000000000008152600160a060020a039283166004820152918d16602483015251919650735f4928c421a53a9aa161d96886299ded68fb76a29163bca9adef91604480820192602092909190829003018186803b158015615b7057600080fd5b505af4158015615b84573d6000803e3d6000fd5b505050506040513d6020811015615b9a57600080fd5b5051989a9799509597949693959193909250565b600082821115615bba57fe5b50900390565b8181018281101561110d57fe5b6000821515615bde5750600061110d565b50818102818382811515615bee57fe5b041461110d57fe5b600160a060020a0381161515615c0b57600080fd5b60008054604051600160a060020a03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a360008054600160a060020a031916600160a060020a0392909216919091179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615ca757805160ff1916838001178555615cd4565b82800160010185558215615cd4579182015b82811115615cd4578251825591602001919060010190615cb9565b50615ce0929150615ce4565b5090565b610e9091905b80821115615ce05760008155600101615cea5600ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa165627a7a723058207c35ca72ac77a98c735fe3da0e9208f4e6afbcd86719711e675883cd5caa00f40029

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

000000000000000000000000fc8deeb5cd80a3e8b8de353df9b5b09c71d3ef17000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000a63737453746f7261676500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b6c65646765722d43415244000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _registry (address): 0xfc8dEeB5cD80A3e8B8DE353Df9b5b09c71d3Ef17
Arg [1] : _storageName (string): cstStorage
Arg [2] : _ledgerName (string): ledger-CARD

-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 000000000000000000000000fc8deeb5cd80a3e8b8de353df9b5b09c71d3ef17
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [3] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [4] : 63737453746f7261676500000000000000000000000000000000000000000000
Arg [5] : 000000000000000000000000000000000000000000000000000000000000000b
Arg [6] : 6c65646765722d43415244000000000000000000000000000000000000000000


Libraries Used


Swarm Source

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