ETH Price: $3,457.17 (+3.88%)

Contract

0xC2A9D8DAA3a9c22fCAefeAa35938d8638471479D
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x60806040145274352022-04-05 17:58:42964 days ago1649181522IN
 Create: MultiNodeV2
0 ETH0.48860251110

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
212614922024-11-25 1:29:3511 hrs ago1732498175
0xC2A9D8DA...38471479D
0.00311023 ETH
212599452024-11-24 20:18:5917 hrs ago1732479539
0xC2A9D8DA...38471479D
0.00311023 ETH
212599432024-11-24 20:18:3517 hrs ago1732479515
0xC2A9D8DA...38471479D
0.00311023 ETH
212573772024-11-24 11:42:4725 hrs ago1732448567
0xC2A9D8DA...38471479D
0.00311023 ETH
212573742024-11-24 11:42:1125 hrs ago1732448531
0xC2A9D8DA...38471479D
0.00311023 ETH
212573712024-11-24 11:41:3525 hrs ago1732448495
0xC2A9D8DA...38471479D
0.00311023 ETH
212573282024-11-24 11:32:4725 hrs ago1732447967
0xC2A9D8DA...38471479D
0.00311023 ETH
212573222024-11-24 11:31:3525 hrs ago1732447895
0xC2A9D8DA...38471479D
0.00311023 ETH
212496172024-11-23 9:42:592 days ago1732354979
0xC2A9D8DA...38471479D
0.00311023 ETH
212377172024-11-21 17:52:233 days ago1732211543
0xC2A9D8DA...38471479D
0.26094597 ETH
212358412024-11-21 11:35:474 days ago1732188947
0xC2A9D8DA...38471479D
0.00311023 ETH
212342892024-11-21 6:22:474 days ago1732170167
0xC2A9D8DA...38471479D
0.01555118 ETH
212342742024-11-21 6:19:474 days ago1732169987
0xC2A9D8DA...38471479D
0.01555118 ETH
212168052024-11-18 19:50:356 days ago1731959435
0xC2A9D8DA...38471479D
0.00622047 ETH
212168022024-11-18 19:49:596 days ago1731959399
0xC2A9D8DA...38471479D
0.00311023 ETH
212134442024-11-18 8:35:477 days ago1731918947
0xC2A9D8DA...38471479D
0.00311023 ETH
212134402024-11-18 8:34:597 days ago1731918899
0xC2A9D8DA...38471479D
0.00311023 ETH
212030782024-11-16 21:54:238 days ago1731794063
0xC2A9D8DA...38471479D
0.01866141 ETH
212030692024-11-16 21:52:358 days ago1731793955
0xC2A9D8DA...38471479D
0.01866141 ETH
211972362024-11-16 2:21:599 days ago1731723719
0xC2A9D8DA...38471479D
0.00311023 ETH
211940002024-11-15 15:30:359 days ago1731684635
0xC2A9D8DA...38471479D
0.00311023 ETH
211771522024-11-13 7:03:2312 days ago1731481403
0xC2A9D8DA...38471479D
0.02488188 ETH
211754252024-11-13 1:16:4712 days ago1731460607
0xC2A9D8DA...38471479D
0 ETH
211752942024-11-13 0:50:3512 days ago1731459035
0xC2A9D8DA...38471479D
0 ETH
211673582024-11-11 22:14:3513 days ago1731363275
0xC2A9D8DA...38471479D
0.0093307 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MultiNodeV2

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 11 : MultiNodeV2.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.9;

import "./interfaces/IERC20.sol";
import "./interfaces/IMultiNode.sol";
import "./interfaces/IStrongPool.sol";
import "./interfaces/IStrongNFTBonus.sol";
import "./lib/InternalCalls.sol";
import "./lib/MultiNodeSettings.sol";
import "./lib/SbMath.sol";

contract MultiNodeV2 is IMultiNode, InternalCalls, MultiNodeSettings {

  uint private constant _SECONDS_IN_ONE_MINUTE = 60;

  IERC20 public strongToken;
  IStrongNFTBonus public strongNFTBonus;

  uint public totalNodes;
  uint public nodesLimit;
  uint public takeStrongBips;
  address payable public feeCollector;
  mapping(address => bool) private serviceContractEnabled;

  mapping(address => uint) public entityNodeCount;
  mapping(address => uint) public entityCreditUsed;
  mapping(address => mapping(uint => uint)) public entityNodeTypeCount;
  mapping(bytes => uint) public entityNodeType;
  mapping(bytes => uint) public entityNodeCreatedAt;
  mapping(bytes => uint) public entityNodeLastPaidAt;
  mapping(bytes => uint) public entityNodeLastClaimedAt;

  // Events

  event Created(address indexed entity, uint nodeType, uint nodeId, bool usedCredit, uint timestamp);
  event Paid(address indexed entity, uint nodeType, uint nodeId, uint timestamp);
  event Claimed(address indexed entity, uint nodeId, uint reward);
  event MigratedFromService(address indexed service, address indexed entity, uint nodeType, uint nodeId, uint lastPaidAt);
  event SetFeeCollector(address payable collector);
  event SetNFTBonusContract(address strongNFTBonus);
  event SetNodesLimit(uint limit);
  event SetServiceContractEnabled(address service, bool enabled);
  event SetTakeStrongBips(uint bips);

  function init(
    IERC20 _strongToken,
    IStrongNFTBonus _strongNFTBonus,
    address payable _feeCollector
  ) external onlyRole(adminControl.SUPER_ADMIN()) {
    require(_feeCollector != address(0), "no address");

    strongToken = _strongToken;
    strongNFTBonus = _strongNFTBonus;
    feeCollector = _feeCollector;

    InternalCalls.init();
  }

  //
  // Getters
  // -------------------------------------------------------------------------------------------------------------------

  function getRewardBalance() external view returns (uint) {
    return strongToken.balanceOf(address(this));
  }

  function calcDecayedReward(uint _baseRate, uint _decayFactor, uint _minutesPassed) public pure returns (uint) {
    uint power = SbMath._decPow(_decayFactor, _minutesPassed);
    uint cumulativeFraction = SbMath.DECIMAL_PRECISION - power;

    return _baseRate * cumulativeFraction / SbMath.DECIMAL_PRECISION;
  }

  function canNodeBePaid(address _entity, uint _nodeId) public view returns (bool) {
    return doesNodeExist(_entity, _nodeId) && !hasNodeExpired(_entity, _nodeId) && !hasMaxPayments(_entity, _nodeId);
  }

  function doesNodeExist(address _entity, uint _nodeId) public view returns (bool) {
    return entityNodeLastPaidAt[getNodeId(_entity, _nodeId)] > 0;
  }

  function isNodePastDue(address _entity, uint _nodeId) public view returns (bool) {
    bytes memory id = getNodeId(_entity, _nodeId);
    uint nodeType = entityNodeType[id];
    uint lastPaidAt = entityNodeLastPaidAt[id];

    return block.timestamp > (lastPaidAt + getRecurringPaymentCycle(nodeType));
  }

  function hasNodeExpired(address _entity, uint _nodeId) public view returns (bool) {
    bytes memory id = getNodeId(_entity, _nodeId);
    uint nodeType = entityNodeType[id];
    uint lastPaidAt = entityNodeLastPaidAt[id];
    if (lastPaidAt == 0) return true;

    return block.timestamp > (lastPaidAt + getRecurringPaymentCycle(nodeType) + getGracePeriod(nodeType));
  }

  function hasMaxPayments(address _entity, uint _nodeId) public view returns (bool) {
    bytes memory id = getNodeId(_entity, _nodeId);
    uint nodeType = entityNodeType[id];
    uint lastPaidAt = entityNodeLastPaidAt[id];
    uint recurringPaymentCycle = getRecurringPaymentCycle(nodeType);
    uint limit = block.timestamp + recurringPaymentCycle * getPayCyclesLimit(nodeType);

    return lastPaidAt + recurringPaymentCycle >= limit;
  }

  function getNodeId(address _entity, uint _nodeId) public view returns (bytes memory) {
    uint id = _nodeId != 0 ? _nodeId : entityNodeCount[_entity] + 1;
    return abi.encodePacked(_entity, id);
  }

  function getNodeType(address _entity, uint _nodeId) public view returns (uint) {
    return entityNodeType[getNodeId(_entity, _nodeId)];
  }

  function getNodeRecurringFee(address _entity, uint _nodeId) external view returns (uint) {
    return getRecurringFeeInWei(entityNodeType[getNodeId(_entity, _nodeId)]);
  }

  function getNodeClaimingFee(address _entity, uint _nodeId, uint _timestamp) external view returns (uint) {
    uint nodeType = entityNodeType[getNodeId(_entity, _nodeId)];
    uint reward = getRewardAt(_entity, _nodeId, _timestamp);
    return reward * getClaimingFeeNumerator(nodeType) / getClaimingFeeDenominator(nodeType);
  }

  function getNodePaidOn(address _entity, uint _nodeId) external view returns (uint) {
    return entityNodeLastPaidAt[getNodeId(_entity, _nodeId)];
  }

  function getNodeReward(address _entity, uint _nodeId) external view returns (uint) {
    return getRewardAt(_entity, _nodeId, block.timestamp);
  }

  function getRewardAt(address _entity, uint _nodeId, uint _timestamp) public view returns (uint) {
    bytes memory id = getNodeId(_entity, _nodeId);
    uint nodeType = entityNodeType[id];
    uint lastClaimedAt = entityNodeLastClaimedAt[id] != 0 ? entityNodeLastClaimedAt[id] : entityNodeCreatedAt[id];
    uint registeredAt = entityNodeCreatedAt[id];

    if (!doesNodeExist(_entity, _nodeId)) return 0;
    if (hasNodeExpired(_entity, _nodeId)) return 0;
    if (_timestamp > block.timestamp) return 0;
    if (_timestamp <= lastClaimedAt) return 0;

    uint minutesTotal = (_timestamp - registeredAt) / _SECONDS_IN_ONE_MINUTE;

    uint reward = calcDecayedReward(
      getRewardBaseRate(nodeType),
      getRewardDecayFactor(nodeType),
      minutesTotal
    );

    if (lastClaimedAt > 0) {
      uint minutesToLastClaim = (lastClaimedAt - registeredAt) / _SECONDS_IN_ONE_MINUTE;
      uint rewardAtLastClaim = calcDecayedReward(getRewardBaseRate(nodeType), getRewardDecayFactor(nodeType), minutesToLastClaim);
      reward = reward - rewardAtLastClaim;
    }

    uint bonus = getNftBonusAt(_entity, _nodeId, _timestamp);

    return reward + bonus;
  }

  function getNftBonusAt(address _entity, uint _nodeId, uint _timestamp) public view returns (uint) {
    if (address(strongNFTBonus) == address(0)) return 0;

    bytes memory id = getNodeId(_entity, _nodeId);
    uint nodeType = entityNodeType[id];
    uint lastClaimedAt = entityNodeLastClaimedAt[id] != 0 ? entityNodeLastClaimedAt[id] : entityNodeCreatedAt[id];
    string memory bonusName = strongNFTBonus.getStakedNftBonusName(_entity, uint128(_nodeId), address(this));

    if (keccak256(abi.encode(bonusName)) == keccak256(abi.encode(""))) return 0;

    uint bonusValue = getNftBonusValue(nodeType, bonusName);

    return bonusValue > 0
    ? strongNFTBonus.getBonusValue(_entity, uint128(_nodeId), lastClaimedAt, _timestamp, bonusValue)
    : 0;
  }

  function getEntityRewards(address _entity, uint _timestamp) public view returns (uint) {
    uint reward = 0;

    for (uint nodeId = 1; nodeId <= entityNodeCount[_entity]; nodeId++) {
      reward = reward + getRewardAt(_entity, nodeId, _timestamp > 0 ? _timestamp : block.timestamp);
    }

    return reward;
  }

  function getEntityCreditAvailable(address _entity, uint _timestamp) public view returns (uint) {
    return getEntityRewards(_entity, _timestamp) - entityCreditUsed[_entity];
  }

  function getNodesRecurringFee(address _entity, uint _fromNode, uint _toNode) external view returns (uint) {
    uint fee = 0;
    uint fromNode = _fromNode > 0 ? _fromNode : 1;
    uint toNode = _toNode > 0 ? _toNode : entityNodeCount[_entity];

    for (uint nodeId = fromNode; nodeId <= toNode; nodeId++) {
      if (canNodeBePaid(_entity, nodeId)) fee = fee + getRecurringFeeInWei(getNodeType(_entity, nodeId));
    }

    return fee;
  }

  function getNodesClaimingFee(address _entity, uint _timestamp, uint _fromNode, uint _toNode) external view returns (uint) {
    uint fee = 0;
    uint fromNode = _fromNode > 0 ? _fromNode : 1;
    uint toNode = _toNode > 0 ? _toNode : entityNodeCount[_entity];

    for (uint nodeId = fromNode; nodeId <= toNode; nodeId++) {
      uint reward = getRewardAt(_entity, nodeId, _timestamp > 0 ? _timestamp : block.timestamp);
      if (reward > 0) {
        uint nodeType = getNodeType(_entity, nodeId);
        fee = fee + reward * getClaimingFeeNumerator(nodeType) / getClaimingFeeDenominator(nodeType);
      }
    }

    return fee;
  }

  //
  // Actions
  // -------------------------------------------------------------------------------------------------------------------

  function createNode(uint _nodeType, bool _useCredit) external payable {
    uint fee = getCreatingFeeInWei(_nodeType);
    uint strongFee = getStrongFeeInWei(_nodeType);
    uint nodeTypeLimit = getNodesLimit(_nodeType);

    require(nodeTypeActive[_nodeType], "invalid type");
    require(nodesLimit == 0 || entityNodeCount[msg.sender] < nodesLimit, "over limit");
    require(nodeTypeLimit == 0 || entityNodeTypeCount[msg.sender][_nodeType] < nodeTypeLimit, "over limit");
    require(msg.value >= fee, "invalid fee");

    uint nodeId = entityNodeCount[msg.sender] + 1;
    bytes memory id = getNodeId(msg.sender, nodeId);

    totalNodes = totalNodes + 1;
    entityNodeType[id] = _nodeType;
    entityNodeCreatedAt[id] = block.timestamp;
    entityNodeLastPaidAt[id] = block.timestamp;
    entityNodeCount[msg.sender] = entityNodeCount[msg.sender] + 1;
    entityNodeTypeCount[msg.sender][_nodeType] = entityNodeTypeCount[msg.sender][_nodeType] + 1;

    emit Created(msg.sender, _nodeType, nodeId, _useCredit, block.timestamp);

    if (_useCredit) {
      require(getEntityCreditAvailable(msg.sender, block.timestamp) >= strongFee, "not enough");
      entityCreditUsed[msg.sender] = entityCreditUsed[msg.sender] + strongFee;
    } else {
      uint takeStrong = strongFee * takeStrongBips / 10000;
      if (takeStrong > 0) {
        require(strongToken.transferFrom(msg.sender, feeCollector, takeStrong), "transfer failed");
      }
      if (strongFee > takeStrong) {
        require(strongToken.transferFrom(msg.sender, address(this), strongFee - takeStrong), "transfer failed");
      }
    }

    sendValue(feeCollector, fee);
    if (msg.value > fee) sendValue(payable(msg.sender), msg.value - fee);
  }

  function claim(uint _nodeId, uint _timestamp, address _toStrongPool) public payable returns (uint) {
    address entity = msg.sender == address(strongNFTBonus) ? tx.origin : msg.sender;
    bytes memory id = getNodeId(entity, _nodeId);
    uint nodeType = entityNodeType[id];
    uint lastClaimedAt = entityNodeLastClaimedAt[id] != 0 ? entityNodeLastClaimedAt[id] : entityNodeCreatedAt[id];

    require(doesNodeExist(entity, _nodeId), "doesnt exist");
    require(!hasNodeExpired(entity, _nodeId), "node expired");
    require(!isNodePastDue(entity, _nodeId), "past due");
    require(_timestamp <= block.timestamp, "bad timestamp");
    require(lastClaimedAt + 900 < _timestamp, "too soon");

    uint reward = getRewardAt(entity, _nodeId, _timestamp);
    require(reward > 0, "no reward");
    require(strongToken.balanceOf(address(this)) >= reward, "over balance");

    uint fee = reward * getClaimingFeeNumerator(nodeType) / getClaimingFeeDenominator(nodeType);
    require(msg.value >= fee, "invalid fee");

    entityNodeLastClaimedAt[id] = _timestamp;

    emit Claimed(entity, _nodeId, reward);

    if (entityCreditUsed[msg.sender] > 0) {
      if (entityCreditUsed[msg.sender] > reward) {
        entityCreditUsed[msg.sender] = entityCreditUsed[msg.sender] - reward;
        reward = 0;
      } else {
        reward = reward - entityCreditUsed[msg.sender];
        entityCreditUsed[msg.sender] = 0;
      }
    }

    if (reward > 0) {
      if (_toStrongPool != address(0)) IStrongPool(_toStrongPool).mineFor(entity, reward);
      else require(strongToken.transfer(entity, reward), "transfer failed");
    }

    sendValue(feeCollector, fee);
    if (isUserCall() && msg.value > fee) sendValue(payable(msg.sender), msg.value - fee);

    return fee;
  }

  function claimAll(uint _timestamp, address _toStrongPool, uint _fromNode, uint _toNode) external payable makesInternalCalls {
    require(entityNodeCount[msg.sender] > 0, "no nodes");

    uint valueLeft = msg.value;
    uint fromNode = _fromNode > 0 ? _fromNode : 1;
    uint toNode = _toNode > 0 ? _toNode : entityNodeCount[msg.sender];

    for (uint nodeId = fromNode; nodeId <= toNode; nodeId++) {
      uint reward = getRewardAt(msg.sender, nodeId, _timestamp);

      if (reward > 0) {
        require(valueLeft > 0, "not enough");
        uint paid = claim(nodeId, _timestamp, _toStrongPool);
        valueLeft = valueLeft - paid;
      }
    }

    if (valueLeft > 0) sendValue(payable(msg.sender), valueLeft);
  }

  function pay(uint _nodeId) public payable returns (uint) {
    bytes memory id = getNodeId(msg.sender, _nodeId);
    uint nodeType = entityNodeType[id];
    uint fee = getRecurringFeeInWei(nodeType);

    require(canNodeBePaid(msg.sender, _nodeId), "cant pay");
    require(msg.value >= fee, "invalid fee");

    entityNodeLastPaidAt[id] = entityNodeLastPaidAt[id] + getRecurringPaymentCycle(nodeType);
    emit Paid(msg.sender, nodeType, _nodeId, entityNodeLastPaidAt[id]);

    sendValue(feeCollector, fee);
    if (isUserCall() && msg.value > fee) sendValue(payable(msg.sender), msg.value - fee);

    return fee;
  }

  function payAll(uint _fromNode, uint _toNode) external payable makesInternalCalls {
    require(entityNodeCount[msg.sender] > 0, "no nodes");

    uint valueLeft = msg.value;
    uint fromNode = _fromNode > 0 ? _fromNode : 1;
    uint toNode = _toNode > 0 ? _toNode : entityNodeCount[msg.sender];

    for (uint nodeId = fromNode; nodeId <= toNode; nodeId++) {
      if (!canNodeBePaid(msg.sender, nodeId)) continue;

      require(valueLeft > 0, "not enough");
      uint paid = pay(nodeId);
      valueLeft = valueLeft - paid;
    }

    if (valueLeft > 0) sendValue(payable(msg.sender), valueLeft);
  }

  function migrateNode(address _entity, uint _nodeType, uint _lastPaidAt) external returns (uint) {
    require(serviceContractEnabled[msg.sender], "no service");
    require(nodeTypeActive[_nodeType], "invalid type");

    uint nodeId = entityNodeCount[_entity] + 1;
    bytes memory id = getNodeId(_entity, nodeId);

    totalNodes = totalNodes + 1;

    entityNodeType[id] = _nodeType;
    entityNodeCreatedAt[id] = _lastPaidAt;
    entityNodeLastPaidAt[id] = _lastPaidAt;
    entityNodeCount[_entity] = entityNodeCount[_entity] + 1;
    entityNodeTypeCount[_entity][_nodeType] = entityNodeTypeCount[_entity][_nodeType] + 1;

    emit MigratedFromService(msg.sender, _entity, _nodeType, nodeId, _lastPaidAt);

    return nodeId;
  }

  //
  // Admin
  // -------------------------------------------------------------------------------------------------------------------

  function deposit(uint _amount) external onlyRole(adminControl.SUPER_ADMIN()) {
    require(_amount > 0);
    require(strongToken.transferFrom(msg.sender, address(this), _amount), "transfer failed");
  }

  function withdraw(address _destination, uint _amount) external onlyRole(adminControl.SUPER_ADMIN()) {
    require(_amount > 0);
    require(strongToken.balanceOf(address(this)) >= _amount, "over balance");
    require(strongToken.transfer(_destination, _amount), "transfer failed");
  }

  function approveStrongPool(IStrongPool _strongPool, uint _amount) external onlyRole(adminControl.SUPER_ADMIN()) {
    require(strongToken.approve(address(_strongPool), _amount), "approve failed");
  }

  function setFeeCollector(address payable _feeCollector) external onlyRole(adminControl.SUPER_ADMIN()) {
    require(_feeCollector != address(0));
    feeCollector = _feeCollector;
    emit SetFeeCollector(_feeCollector);
  }

  function setNFTBonusContract(address _contract) external onlyRole(adminControl.SERVICE_ADMIN()) {
    strongNFTBonus = IStrongNFTBonus(_contract);
    emit SetNFTBonusContract(_contract);
  }

  function setNodesLimit(uint _limit) external onlyRole(adminControl.SERVICE_ADMIN()) {
    nodesLimit = _limit;
    emit SetNodesLimit(_limit);
  }

  function setServiceContractEnabled(address _contract, bool _enabled) external onlyRole(adminControl.SERVICE_ADMIN()) {
    serviceContractEnabled[_contract] = _enabled;
    emit SetServiceContractEnabled(_contract, _enabled);
  }

  function setTakeStrongBips(uint _bips) external onlyRole(adminControl.SUPER_ADMIN()) {
    require(_bips <= 10000, "invalid value");
    takeStrongBips = _bips;
    emit SetTakeStrongBips(_bips);
  }

  function sendValue(address payable recipient, uint256 amount) internal {
    require(address(this).balance >= amount, "insufficient balance");

    // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
    (bool success,) = recipient.call{value : amount}("");
    require(success, "send failed");
  }

  function setTokenContract(IERC20 tokenAddress) external onlyRole(adminControl.SUPER_ADMIN()) {
    strongToken = tokenAddress;
  }

  function withdrawToken(IERC20 token, address recipient, uint256 amount) external onlyRole(adminControl.SUPER_ADMIN()) {
    require(token.transfer(recipient, amount));
  }
}

File 2 of 11 : IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
  /**
   * @dev Returns the amount of tokens in existence.
   */
  function totalSupply() external view returns (uint256);

  /**
   * @dev Returns the amount of tokens owned by `account`.
   */
  function balanceOf(address account) external view returns (uint256);

  /**
   * @dev Moves `amount` tokens from the caller's account to `recipient`.
   *
   * Returns a boolean value indicating whether the operation succeeded.
   *
   * Emits a {Transfer} event.
   */
  function transfer(address recipient, uint256 amount) external returns (bool);

  /**
   * @dev Returns the remaining number of tokens that `spender` will be
   * allowed to spend on behalf of `owner` through {transferFrom}. This is
   * zero by default.
   *
   * This value changes when {approve} or {transferFrom} are called.
   */
  function allowance(address owner, address spender) external view returns (uint256);

  /**
   * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
   *
   * Returns a boolean value indicating whether the operation succeeded.
   *
   * IMPORTANT: 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
   *
   * Emits an {Approval} event.
   */
  function approve(address spender, uint256 amount) external returns (bool);

  /**
   * @dev Moves `amount` tokens from `sender` to `recipient` using the
   * allowance mechanism. `amount` is then deducted from the caller's
   * allowance.
   *
   * Returns a boolean value indicating whether the operation succeeded.
   *
   * Emits a {Transfer} event.
   */
  function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

  /**
   * @dev Emitted when `value` tokens are moved from one account (`from`) to
   * another (`to`).
   *
   * Note that `value` may be zero.
   */
  event Transfer(address indexed from, address indexed to, uint256 value);

  /**
   * @dev Emitted when the allowance of a `spender` for an `owner` is set by
   * a call to {approve}. `value` is the new allowance.
   */
  event Approval(address indexed owner, address indexed spender, uint256 value);
}

File 3 of 11 : IMultiNode.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0;

interface IMultiNode {
  function doesNodeExist(address entity, uint nodeId) external view returns (bool);

  function hasNodeExpired(address entity, uint nodeId) external view returns (bool);

  function claim(uint nodeId, uint timestamp, address toStrongPool) external payable returns (uint);
}

File 4 of 11 : IStrongPool.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0;

interface IStrongPool {
  function mineFor(address miner, uint256 amount) external;
}

File 5 of 11 : IStrongNFTBonus.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0;

interface IStrongNFTBonus {
  function getBonus(address _entity, uint128 _nodeId, uint256 _from, uint256 _to) external view returns (uint256);

  function getBonusValue(address _entity, uint128 _nodeId, uint256 _from, uint256 _to, uint256 _bonusValue) external view returns (uint256);

  function getStakedNftBonusName(address _entity, uint128 _nodeId, address _serviceContract) external view returns (string memory);

  function migrateNFT(address _entity, uint128 _fromNodeId, uint128 _toNodeId, address _toServiceContract) external;
}

File 6 of 11 : InternalCalls.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0;

import "./Context.sol";

abstract contract InternalCalls is Context {

  uint private constant _NOT_MAKING_INTERNAL_CALLS = 1;
  uint private constant _MAKING_INTERNAL_CALLS = 2;

  uint private _internal_calls_status;

  modifier makesInternalCalls() {
    _internal_calls_status = _MAKING_INTERNAL_CALLS;
    _;
    _internal_calls_status = _NOT_MAKING_INTERNAL_CALLS;
  }

  function init() internal {
    _internal_calls_status = _NOT_MAKING_INTERNAL_CALLS;
  }

  function isInternalCall() internal view returns (bool) {
    return _internal_calls_status == _MAKING_INTERNAL_CALLS;
  }

  function isContractCall() internal view returns (bool) {
    return _msgSender() != tx.origin;
  }

  function isUserCall() internal view returns (bool) {
    return !isInternalCall() && !isContractCall();
  }
}

File 7 of 11 : MultiNodeSettings.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0;

import "./AdminAccess.sol";

contract MultiNodeSettings is AdminAccess {

  uint constant public NODE_TYPE_REWARD_BASE_RATE = 0;
  uint constant public NODE_TYPE_REWARD_DECAY_FACTOR = 1;
  uint constant public NODE_TYPE_FEE_STRONG = 2;
  uint constant public NODE_TYPE_FEE_CREATE = 3;
  uint constant public NODE_TYPE_FEE_RECURRING = 4;
  uint constant public NODE_TYPE_FEE_CLAIMING_NUMERATOR = 5;
  uint constant public NODE_TYPE_FEE_CLAIMING_DENOMINATOR = 6;
  uint constant public NODE_TYPE_RECURRING_CYCLE_SECONDS = 7;
  uint constant public NODE_TYPE_GRACE_PERIOD_SECONDS = 8;
  uint constant public NODE_TYPE_PAY_CYCLES_LIMIT = 9;
  uint constant public NODE_TYPE_NODES_LIMIT = 10;

  mapping(uint => bool) public nodeTypeActive;
  mapping(uint => bool) public nodeTypeHasSettings;
  mapping(uint => mapping(uint => uint)) public nodeTypeSettings;
  mapping(uint => mapping(string => uint)) public nodeTypeNFTBonus;

  // Events

  event SetNodeTypeActive(uint nodeType, bool active);
  event SetNodeTypeSetting(uint nodeType, uint settingId, uint value);
  event SetNodeTypeHasSettings(uint nodeType, bool hasSettings);
  event SetNodeTypeNFTBonus(uint nodeType, string bonusName, uint value);

  //
  // Getters
  // -------------------------------------------------------------------------------------------------------------------

  function getRewardBaseRate(uint _nodeType) public view returns (uint) {
    return getCustomSettingOrDefaultIfZero(_nodeType, NODE_TYPE_REWARD_BASE_RATE);
  }

  function getRewardDecayFactor(uint _nodeType) public view returns (uint) {
    return getCustomSettingOrDefaultIfZero(_nodeType, NODE_TYPE_REWARD_DECAY_FACTOR);
  }

  function getClaimingFeeNumerator(uint _nodeType) public view returns (uint) {
    return getCustomSettingOrDefaultIfZero(_nodeType, NODE_TYPE_FEE_CLAIMING_NUMERATOR);
  }

  function getClaimingFeeDenominator(uint _nodeType) public view returns (uint) {
    return getCustomSettingOrDefaultIfZero(_nodeType, NODE_TYPE_FEE_CLAIMING_DENOMINATOR);
  }

  function getCreatingFeeInWei(uint _nodeType) public view returns (uint) {
    return getCustomSettingOrDefaultIfZero(_nodeType, NODE_TYPE_FEE_CREATE);
  }

  function getRecurringFeeInWei(uint _nodeType) public view returns (uint) {
    return getCustomSettingOrDefaultIfZero(_nodeType, NODE_TYPE_FEE_RECURRING);
  }

  function getStrongFeeInWei(uint _nodeType) public view returns (uint) {
    return getCustomSettingOrDefaultIfZero(_nodeType, NODE_TYPE_FEE_STRONG);
  }

  function getRecurringPaymentCycle(uint _nodeType) public view returns (uint) {
    return getCustomSettingOrDefaultIfZero(_nodeType, NODE_TYPE_RECURRING_CYCLE_SECONDS);
  }

  function getGracePeriod(uint _nodeType) public view returns (uint) {
    return getCustomSettingOrDefaultIfZero(_nodeType, NODE_TYPE_GRACE_PERIOD_SECONDS);
  }

  function getPayCyclesLimit(uint _nodeType) public view returns (uint) {
    return getCustomSettingOrDefaultIfZero(_nodeType, NODE_TYPE_PAY_CYCLES_LIMIT);
  }

  function getNodesLimit(uint _nodeType) public view returns (uint) {
    return getCustomSettingOrDefaultIfZero(_nodeType, NODE_TYPE_NODES_LIMIT);
  }

  function getNftBonusValue(uint _nodeType, string memory _bonusName) public view returns (uint) {
    return nodeTypeNFTBonus[_nodeType][_bonusName] > 0
    ? nodeTypeNFTBonus[_nodeType][_bonusName]
    : nodeTypeNFTBonus[0][_bonusName];
  }

  //
  // Setters
  // -------------------------------------------------------------------------------------------------------------------

  function setNodeTypeActive(uint _nodeType, bool _active) external onlyRole(adminControl.SERVICE_ADMIN()) {
    // Node type 0 is being used as a placeholder for the default settings for node types that don't have custom ones,
    // So it shouldn't be activated and used to create nodes
    require(_nodeType > 0, "invalid type");
    nodeTypeActive[_nodeType] = _active;
    emit SetNodeTypeActive(_nodeType, _active);
  }

  function setNodeTypeHasSettings(uint _nodeType, bool _hasSettings) external onlyRole(adminControl.SERVICE_ADMIN()) {
    nodeTypeHasSettings[_nodeType] = _hasSettings;
    emit SetNodeTypeHasSettings(_nodeType, _hasSettings);
  }

  function setNodeTypeSetting(uint _nodeType, uint _settingId, uint _value) external onlyRole(adminControl.SERVICE_ADMIN()) {
    nodeTypeHasSettings[_nodeType] = true;
    nodeTypeSettings[_nodeType][_settingId] = _value;
    emit SetNodeTypeSetting(_nodeType, _settingId, _value);
  }

  function setNodeTypeNFTBonus(uint _nodeType, string memory _bonusName, uint _value) external onlyRole(adminControl.SERVICE_ADMIN()) {
    nodeTypeNFTBonus[_nodeType][_bonusName] = _value;
    emit SetNodeTypeNFTBonus(_nodeType, _bonusName, _value);
  }

  // -------------------------------------------------------------------------------------------------------------------

  function getCustomSettingOrDefaultIfZero(uint _nodeType, uint _setting) internal view returns (uint) {
    return nodeTypeHasSettings[_nodeType] && nodeTypeSettings[_nodeType][_setting] > 0
    ? nodeTypeSettings[_nodeType][_setting]
    : nodeTypeSettings[0][_setting];
  }

}

File 8 of 11 : SbMath.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.8.0;

library SbMath {

  uint internal constant DECIMAL_PRECISION = 1e18;

  /*
  * Multiply two decimal numbers and use normal rounding rules:
  * -round product up if 19'th mantissa digit >= 5
  * -round product down if 19'th mantissa digit < 5
  *
  * Used only inside the exponentiation, _decPow().
  */
  function decMul(uint x, uint y) internal pure returns (uint decProd) {
    uint prod_xy = x * y;

    decProd = (prod_xy + (DECIMAL_PRECISION / 2)) / DECIMAL_PRECISION;
  }

  /*
  * _decPow: Exponentiation function for 18-digit decimal base, and integer exponent n.
  *
  * Uses the efficient "exponentiation by squaring" algorithm. O(log(n)) complexity.
  *
  * The exponent is capped to avoid reverting due to overflow. The cap 525600000 equals
  * "minutes in 1000 years": 60 * 24 * 365 * 1000
  */
  function _decPow(uint _base, uint _minutes) internal pure returns (uint) {

    if (_minutes > 525_600_000) _minutes = 525_600_000;  // cap to avoid overflow

    if (_minutes == 0) return DECIMAL_PRECISION;

    uint y = DECIMAL_PRECISION;
    uint x = _base;
    uint n = _minutes;

    // Exponentiation-by-squaring
    while (n > 1) {
      if (n % 2 == 0) {
        x = decMul(x, x);
        n = n / 2;
      } else { // if (n % 2 != 0)
        y = decMul(x, y);
        x = decMul(x, x);
        n = (n - 1) / 2;
      }
    }

    return decMul(x, y);
  }

}

File 9 of 11 : Context.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

File 10 of 11 : AdminAccess.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0;

import "../interfaces/IAdminControl.sol";

abstract contract AdminAccess {

  IAdminControl public adminControl;

  modifier onlyRole(uint8 _role) {
    require(address(adminControl) == address(0) || adminControl.hasRole(_role, msg.sender), "no access");
    _;
  }

  function addAdminControlContract(IAdminControl _contract) external onlyRole(0) {
    adminControl = _contract;
  }

}

File 11 of 11 : IAdminControl.sol
// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0;

interface IAdminControl {
  function hasRole(uint8 _role, address _account) external view returns (bool);

  function SUPER_ADMIN() external view returns (uint8);

  function ADMIN() external view returns (uint8);

  function SERVICE_ADMIN() external view returns (uint8);
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "metadata": {
    "useLiteralContent": true
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"entity","type":"address"},{"indexed":false,"internalType":"uint256","name":"nodeId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"Claimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"entity","type":"address"},{"indexed":false,"internalType":"uint256","name":"nodeType","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nodeId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"usedCredit","type":"bool"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Created","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"service","type":"address"},{"indexed":true,"internalType":"address","name":"entity","type":"address"},{"indexed":false,"internalType":"uint256","name":"nodeType","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nodeId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastPaidAt","type":"uint256"}],"name":"MigratedFromService","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"entity","type":"address"},{"indexed":false,"internalType":"uint256","name":"nodeType","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nodeId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Paid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address payable","name":"collector","type":"address"}],"name":"SetFeeCollector","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"strongNFTBonus","type":"address"}],"name":"SetNFTBonusContract","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"nodeType","type":"uint256"},{"indexed":false,"internalType":"bool","name":"active","type":"bool"}],"name":"SetNodeTypeActive","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"nodeType","type":"uint256"},{"indexed":false,"internalType":"bool","name":"hasSettings","type":"bool"}],"name":"SetNodeTypeHasSettings","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"nodeType","type":"uint256"},{"indexed":false,"internalType":"string","name":"bonusName","type":"string"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"SetNodeTypeNFTBonus","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"nodeType","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"settingId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"SetNodeTypeSetting","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"limit","type":"uint256"}],"name":"SetNodesLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"service","type":"address"},{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"}],"name":"SetServiceContractEnabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"bips","type":"uint256"}],"name":"SetTakeStrongBips","type":"event"},{"inputs":[],"name":"NODE_TYPE_FEE_CLAIMING_DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NODE_TYPE_FEE_CLAIMING_NUMERATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NODE_TYPE_FEE_CREATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NODE_TYPE_FEE_RECURRING","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NODE_TYPE_FEE_STRONG","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NODE_TYPE_GRACE_PERIOD_SECONDS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NODE_TYPE_NODES_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NODE_TYPE_PAY_CYCLES_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NODE_TYPE_RECURRING_CYCLE_SECONDS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NODE_TYPE_REWARD_BASE_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NODE_TYPE_REWARD_DECAY_FACTOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IAdminControl","name":"_contract","type":"address"}],"name":"addAdminControlContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"adminControl","outputs":[{"internalType":"contract IAdminControl","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IStrongPool","name":"_strongPool","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"approveStrongPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_baseRate","type":"uint256"},{"internalType":"uint256","name":"_decayFactor","type":"uint256"},{"internalType":"uint256","name":"_minutesPassed","type":"uint256"}],"name":"calcDecayedReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_entity","type":"address"},{"internalType":"uint256","name":"_nodeId","type":"uint256"}],"name":"canNodeBePaid","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nodeId","type":"uint256"},{"internalType":"uint256","name":"_timestamp","type":"uint256"},{"internalType":"address","name":"_toStrongPool","type":"address"}],"name":"claim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_timestamp","type":"uint256"},{"internalType":"address","name":"_toStrongPool","type":"address"},{"internalType":"uint256","name":"_fromNode","type":"uint256"},{"internalType":"uint256","name":"_toNode","type":"uint256"}],"name":"claimAll","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nodeType","type":"uint256"},{"internalType":"bool","name":"_useCredit","type":"bool"}],"name":"createNode","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_entity","type":"address"},{"internalType":"uint256","name":"_nodeId","type":"uint256"}],"name":"doesNodeExist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"entityCreditUsed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"entityNodeCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"entityNodeCreatedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"entityNodeLastClaimedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"entityNodeLastPaidAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"","type":"bytes"}],"name":"entityNodeType","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"entityNodeTypeCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeCollector","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nodeType","type":"uint256"}],"name":"getClaimingFeeDenominator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nodeType","type":"uint256"}],"name":"getClaimingFeeNumerator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nodeType","type":"uint256"}],"name":"getCreatingFeeInWei","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_entity","type":"address"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"getEntityCreditAvailable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_entity","type":"address"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"getEntityRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nodeType","type":"uint256"}],"name":"getGracePeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_entity","type":"address"},{"internalType":"uint256","name":"_nodeId","type":"uint256"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"getNftBonusAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nodeType","type":"uint256"},{"internalType":"string","name":"_bonusName","type":"string"}],"name":"getNftBonusValue","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_entity","type":"address"},{"internalType":"uint256","name":"_nodeId","type":"uint256"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"getNodeClaimingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_entity","type":"address"},{"internalType":"uint256","name":"_nodeId","type":"uint256"}],"name":"getNodeId","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_entity","type":"address"},{"internalType":"uint256","name":"_nodeId","type":"uint256"}],"name":"getNodePaidOn","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_entity","type":"address"},{"internalType":"uint256","name":"_nodeId","type":"uint256"}],"name":"getNodeRecurringFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_entity","type":"address"},{"internalType":"uint256","name":"_nodeId","type":"uint256"}],"name":"getNodeReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_entity","type":"address"},{"internalType":"uint256","name":"_nodeId","type":"uint256"}],"name":"getNodeType","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_entity","type":"address"},{"internalType":"uint256","name":"_timestamp","type":"uint256"},{"internalType":"uint256","name":"_fromNode","type":"uint256"},{"internalType":"uint256","name":"_toNode","type":"uint256"}],"name":"getNodesClaimingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nodeType","type":"uint256"}],"name":"getNodesLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_entity","type":"address"},{"internalType":"uint256","name":"_fromNode","type":"uint256"},{"internalType":"uint256","name":"_toNode","type":"uint256"}],"name":"getNodesRecurringFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nodeType","type":"uint256"}],"name":"getPayCyclesLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nodeType","type":"uint256"}],"name":"getRecurringFeeInWei","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nodeType","type":"uint256"}],"name":"getRecurringPaymentCycle","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_entity","type":"address"},{"internalType":"uint256","name":"_nodeId","type":"uint256"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"getRewardAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRewardBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nodeType","type":"uint256"}],"name":"getRewardBaseRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nodeType","type":"uint256"}],"name":"getRewardDecayFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nodeType","type":"uint256"}],"name":"getStrongFeeInWei","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_entity","type":"address"},{"internalType":"uint256","name":"_nodeId","type":"uint256"}],"name":"hasMaxPayments","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_entity","type":"address"},{"internalType":"uint256","name":"_nodeId","type":"uint256"}],"name":"hasNodeExpired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_strongToken","type":"address"},{"internalType":"contract IStrongNFTBonus","name":"_strongNFTBonus","type":"address"},{"internalType":"address payable","name":"_feeCollector","type":"address"}],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_entity","type":"address"},{"internalType":"uint256","name":"_nodeId","type":"uint256"}],"name":"isNodePastDue","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_entity","type":"address"},{"internalType":"uint256","name":"_nodeType","type":"uint256"},{"internalType":"uint256","name":"_lastPaidAt","type":"uint256"}],"name":"migrateNode","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"nodeTypeActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"nodeTypeHasSettings","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"string","name":"","type":"string"}],"name":"nodeTypeNFTBonus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"nodeTypeSettings","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nodesLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nodeId","type":"uint256"}],"name":"pay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_fromNode","type":"uint256"},{"internalType":"uint256","name":"_toNode","type":"uint256"}],"name":"payAll","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_feeCollector","type":"address"}],"name":"setFeeCollector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"}],"name":"setNFTBonusContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nodeType","type":"uint256"},{"internalType":"bool","name":"_active","type":"bool"}],"name":"setNodeTypeActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nodeType","type":"uint256"},{"internalType":"bool","name":"_hasSettings","type":"bool"}],"name":"setNodeTypeHasSettings","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nodeType","type":"uint256"},{"internalType":"string","name":"_bonusName","type":"string"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"setNodeTypeNFTBonus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nodeType","type":"uint256"},{"internalType":"uint256","name":"_settingId","type":"uint256"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"setNodeTypeSetting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_limit","type":"uint256"}],"name":"setNodesLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_contract","type":"address"},{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setServiceContractEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_bips","type":"uint256"}],"name":"setTakeStrongBips","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"tokenAddress","type":"address"}],"name":"setTokenContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"strongNFTBonus","outputs":[{"internalType":"contract IStrongNFTBonus","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"strongToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"takeStrongBips","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalNodes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_destination","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b50614f65806100206000396000f3fe6080604052600436106104895760003560e01c80639548f1e611610255578063c8f064ec11610144578063e79ae18b116100c1578063f232ee3711610085578063f232ee3714610e7e578063f3fef3a314610e93578063f5474cb014610eb3578063f9df21e714610ed3578063fade29de14610ef3578063fefe2f5814610f1357600080fd5b8063e79ae18b14610db9578063e94d59dc14610df1578063ea97bba614610e11578063eaace4cc14610e49578063eaffeddc14610e5e57600080fd5b8063dd811fff11610108578063dd811fff14610d31578063de20d47a14610d51578063e0b5485914610d71578063e2ca3c3a14610d84578063e5f4f66714610da457600080fd5b8063c8f064ec14610c8e578063d1c25be314610ca3578063d2d7b21414610cc3578063d7feb2fe14610cd9578063dc2e86e914610d1157600080fd5b8063ac44ff31116101d2578063bbcd5bbe11610196578063bbcd5bbe14610bfb578063c290d69114610c1b578063c415b95c14610c2e578063c548201114610c4e578063c741643714610c6e57600080fd5b8063ac44ff3114610b75578063afc9a71b14610b88578063b6b55f2514610b9b578063b7fef4ce14610bbb578063bbbf0f6614610bdb57600080fd5b8063a42dce8011610219578063a42dce8014610ac8578063a5ea985d14610ae8578063a77e282514610b08578063aa81ce3e14610b35578063aadea3f314610b5557600080fd5b80639548f1e614610a325780639592d42414610a52578063965d61b914610a685780639daf08c014610a88578063a052058114610aa857600080fd5b80635041ae2b1161037c5780636fdd1ff1116102f9578063855f261e116102bd578063855f261e1461094a5780638ccf7f23146109825780638ecddc05146109b25780638eda065f146109d25780639145e391146109f2578063939c6bfb14610a1257600080fd5b80636fdd1ff11461089257806373d70677146108b257806378a76066146108d25780637a0b92551461090a57806381e79c0c1461092a57600080fd5b8063555d3e6311610340578063555d3e63146107e5578063572887b01461081d5780635e42b4551461083d57806361a3aa8e1461085257806363a441021461087257600080fd5b80635041ae2b1461073b57806350d0eed014610750578063528402791461076557806353663f7b1461078557806355079ddd146107c557600080fd5b806327bee7471161040a5780634608482d116103ce5780634608482d146106725780634de740ba146106925780634df78d5f146106b25780634ff63422146106d25780634ffbcc0c1461071b57600080fd5b806327bee747146105e557806331ed56f9146105fb578063342ec83d146106105780633bc16d701461063d57806341e666911461065257600080fd5b806311d7096d1161045157806311d7096d1461055d578063184b95591461057d57806319ba32631461059d57806321d2ab8a146105bd5780632749bf4f146105d257600080fd5b806301bd2f811461048e57806301e33667146104d9578063030fca67146104fb5780630c056e411461051b5780630c931cd014610548575b600080fd5b34801561049a57600080fd5b506104c66104a93660046147eb565b600f60209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b3480156104e557600080fd5b506104f96104f4366004614817565b610f28565b005b34801561050757600080fd5b506104c6610516366004614858565b6110f9565b34801561052757600080fd5b5061053b6105363660046147eb565b61118a565b6040516104d091906148e5565b34801561055457600080fd5b506104c6600181565b34801561056957600080fd5b506104c66105783660046148f8565b611200565b34801561058957600080fd5b506104f9610598366004614911565b61120d565b3480156105a957600080fd5b506104c66105b83660046148f8565b6113ce565b3480156105c957600080fd5b506104c6600881565b6104f96105e036600461495c565b6113db565b3480156105f157600080fd5b506104c660095481565b34801561060757600080fd5b506104c6600081565b34801561061c57600080fd5b506104c661062b366004614999565b600e6020526000908152604090205481565b34801561064957600080fd5b506104c6600a81565b34801561065e57600080fd5b506104c661066d3660046149b6565b6114e8565b34801561067e57600080fd5b506104c661068d3660046148f8565b611534565b34801561069e57600080fd5b506104f96106ad3660046149f0565b611541565b3480156106be57600080fd5b506104f96106cd366004614999565b6116d3565b3480156106de57600080fd5b506104c66106ed366004614aed565b6005602090815260009283526040909220815180830184018051928152908401929093019190912091525481565b34801561072757600080fd5b506104f96107363660046149b6565b611860565b34801561074757600080fd5b506104c6600681565b34801561075c57600080fd5b506104c6600781565b34801561077157600080fd5b506104f96107803660046148f8565b611a0b565b34801561079157600080fd5b506107b56107a03660046148f8565b60036020526000908152604090205460ff1681565b60405190151581526020016104d0565b3480156107d157600080fd5b506104c66107e03660046147eb565b611b77565b3480156107f157600080fd5b50600154610805906001600160a01b031681565b6040516001600160a01b0390911681526020016104d0565b34801561082957600080fd5b506104c66108383660046148f8565b611bdb565b34801561084957600080fd5b506104c6611be8565b34801561085e57600080fd5b506104f961086d3660046149f0565b611c69565b34801561087e57600080fd5b506104f961088d366004614b34565b611e12565b34801561089e57600080fd5b506104f96108ad3660046148f8565b611fb0565b3480156108be57600080fd5b506104c66108cd366004614858565b61215e565b3480156108de57600080fd5b506104c66108ed366004614b84565b805160208183018101805160108252928201919093012091525481565b34801561091657600080fd5b506104f9610925366004614999565b612356565b34801561093657600080fd5b506104c66109453660046147eb565b61242d565b34801561095657600080fd5b506104c6610965366004614b84565b805160208183018101805160138252928201919093012091525481565b34801561098e57600080fd5b506107b561099d3660046148f8565b60026020526000908152604090205460ff1681565b3480156109be57600080fd5b506104c66109cd366004614858565b61245f565b3480156109de57600080fd5b506104c66109ed3660046147eb565b61262c565b3480156109fe57600080fd5b506104c6610a0d366004614858565b612659565b348015610a1e57600080fd5b506104c6610a2d3660046147eb565b6126b1565b348015610a3e57600080fd5b50600754610805906001600160a01b031681565b348015610a5e57600080fd5b506104c660085481565b348015610a7457600080fd5b50600654610805906001600160a01b031681565b348015610a9457600080fd5b506107b5610aa33660046147eb565b6126be565b348015610ab457600080fd5b506104c6610ac33660046148f8565b6126f2565b348015610ad457600080fd5b506104f9610ae3366004614999565b6126ff565b348015610af457600080fd5b506104c6610b033660046147eb565b612897565b348015610b1457600080fd5b506104c6610b23366004614999565b600d6020526000908152604090205481565b348015610b4157600080fd5b506107b5610b503660046147eb565b6128c9565b348015610b6157600080fd5b506104c6610b703660046148f8565b612901565b6104c6610b83366004614bcd565b61290e565b6104f9610b963660046149f0565b612ecd565b348015610ba757600080fd5b506104f9610bb63660046148f8565b61337e565b348015610bc757600080fd5b506104c6610bd63660046147eb565b61356c565b348015610be757600080fd5b506104c6610bf63660046148f8565b61357a565b348015610c0757600080fd5b506104f9610c16366004614999565b613587565b6104c6610c293660046148f8565b6136e1565b348015610c3a57600080fd5b50600b54610805906001600160a01b031681565b348015610c5a57600080fd5b506104c6610c693660046148f8565b61388a565b348015610c7a57600080fd5b506107b5610c893660046147eb565b613897565b348015610c9a57600080fd5b506104c6600481565b348015610caf57600080fd5b506107b5610cbe3660046147eb565b61390b565b348015610ccf57600080fd5b506104c6600a5481565b348015610ce557600080fd5b506104c6610cf4366004614b84565b805160208183018101805160128252928201919093012091525481565b348015610d1d57600080fd5b506104f9610d2c3660046147eb565b61399b565b348015610d3d57600080fd5b506104c6610d4c366004614858565b613b9a565b348015610d5d57600080fd5b506104c6610d6c3660046148f8565b613e1a565b6104f9610d7f366004614bfb565b613e27565b348015610d9057600080fd5b506104f9610d9f366004614c1d565b613f2d565b348015610db057600080fd5b506104c6600281565b348015610dc557600080fd5b506104c6610dd4366004614b84565b805160208183018101805160118252928201919093012091525481565b348015610dfd57600080fd5b506104c6610e0c366004614aed565b6140c0565b348015610e1d57600080fd5b506104c6610e2c366004614bfb565b600460209081526000928352604080842090915290825290205481565b348015610e5557600080fd5b506104c6600381565b348015610e6a57600080fd5b506104c6610e793660046148f8565b61415d565b348015610e8a57600080fd5b506104c6600981565b348015610e9f57600080fd5b506104f9610eae3660046147eb565b61416a565b348015610ebf57600080fd5b506104c6610ece3660046148f8565b614408565b348015610edf57600080fd5b506107b5610eee3660046147eb565b614415565b348015610eff57600080fd5b506104c6610f0e366004614c4b565b6144b1565b348015610f1f57600080fd5b506104c6600581565b600160009054906101000a90046001600160a01b03166001600160a01b0316637c7c7c3c6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f7657600080fd5b505afa158015610f8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fae9190614c86565b6001546001600160a01b031615806110435750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f690610ff39084903390600401614ca9565b60206040518083038186803b15801561100b57600080fd5b505afa15801561101f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110439190614cc5565b6110685760405162461bcd60e51b815260040161105f90614ce2565b60405180910390fd5b60405163a9059cbb60e01b81526001600160a01b0384811660048301526024820184905285169063a9059cbb90604401602060405180830381600087803b1580156110b257600080fd5b505af11580156110c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ea9190614cc5565b6110f357600080fd5b50505050565b600080808461110957600161110b565b845b90506000808511611134576001600160a01b0387166000908152600d6020526040902054611136565b845b9050815b81811161117c5761114b88826128c9565b1561116a5761115d610e79898361242d565b6111679085614d1b565b93505b8061117481614d33565b91505061113a565b5091925050505b9392505050565b60606000826111bc576001600160a01b0384166000908152600d60205260409020546111b7906001614d1b565b6111be565b825b6040516bffffffffffffffffffffffff19606087901b166020820152603481018290529091506054016040516020818303038152906040529150505b92915050565b60006111fa82600a61457e565b600160009054906101000a90046001600160a01b03166001600160a01b0316637c7c7c3c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561125b57600080fd5b505afa15801561126f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112939190614c86565b6001546001600160a01b031615806113285750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f6906112d89084903390600401614ca9565b60206040518083038186803b1580156112f057600080fd5b505afa158015611304573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113289190614cc5565b6113445760405162461bcd60e51b815260040161105f90614ce2565b6001600160a01b0382166113875760405162461bcd60e51b815260206004820152600a6024820152696e6f206164647265737360b01b604482015260640161105f565b600680546001600160a01b038087166001600160a01b03199283161790925560078054868416908316179055600b8054928516929091169190911790556110f36001600055565b60006111fa82600161457e565b60026000908155338152600d60205260409020546114265760405162461bcd60e51b81526020600482015260086024820152676e6f206e6f64657360c01b604482015260640161105f565b34600083611435576001611437565b835b9050600080841161145757336000908152600d6020526040902054611459565b835b9050815b8181116114c957600061147133838b61245f565b905080156114b657600085116114995760405162461bcd60e51b815260040161105f90614d4e565b60006114a6838b8b61290e565b90506114b28187614d72565b9550505b50806114c181614d33565b91505061145d565b5082156114da576114da3384614609565b505060016000555050505050565b6000806114f584846146e1565b9050600061150b82670de0b6b3a7640000614d72565b9050670de0b6b3a76400006115208288614d89565b61152a9190614dbe565b9695505050505050565b60006111fa82600361457e565b600160009054906101000a90046001600160a01b03166001600160a01b0316630fe175bb6040518163ffffffff1660e01b815260040160206040518083038186803b15801561158f57600080fd5b505afa1580156115a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115c79190614c86565b6001546001600160a01b0316158061165c5750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f69061160c9084903390600401614ca9565b60206040518083038186803b15801561162457600080fd5b505afa158015611638573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061165c9190614cc5565b6116785760405162461bcd60e51b815260040161105f90614ce2565b600083815260036020908152604091829020805460ff19168515159081179091558251868152918201527f43310f1a48ae0abe7aa4426ad65f06014365dfb499aaeafa1678bba75ab032ff91015b60405180910390a1505050565b600160009054906101000a90046001600160a01b03166001600160a01b0316630fe175bb6040518163ffffffff1660e01b815260040160206040518083038186803b15801561172157600080fd5b505afa158015611735573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117599190614c86565b6001546001600160a01b031615806117ee5750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f69061179e9084903390600401614ca9565b60206040518083038186803b1580156117b657600080fd5b505afa1580156117ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ee9190614cc5565b61180a5760405162461bcd60e51b815260040161105f90614ce2565b600780546001600160a01b0319166001600160a01b0384169081179091556040519081527fa30ea3596e6b0bf63d799ca3146166f9b51a9eb996ce58e022ef806c13e17ff0906020015b60405180910390a15050565b600160009054906101000a90046001600160a01b03166001600160a01b0316630fe175bb6040518163ffffffff1660e01b815260040160206040518083038186803b1580156118ae57600080fd5b505afa1580156118c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e69190614c86565b6001546001600160a01b0316158061197b5750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f69061192b9084903390600401614ca9565b60206040518083038186803b15801561194357600080fd5b505afa158015611957573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061197b9190614cc5565b6119975760405162461bcd60e51b815260040161105f90614ce2565b6000848152600360209081526040808320805460ff191660011790556004825280832086845282529182902084905581518681529081018590529081018390527fb769bc1108ca077938f2f70329b1f983427891545696672e587358c37bb0187e906060015b60405180910390a150505050565b600160009054906101000a90046001600160a01b03166001600160a01b0316630fe175bb6040518163ffffffff1660e01b815260040160206040518083038186803b158015611a5957600080fd5b505afa158015611a6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a919190614c86565b6001546001600160a01b03161580611b265750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f690611ad69084903390600401614ca9565b60206040518083038186803b158015611aee57600080fd5b505afa158015611b02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b269190614cc5565b611b425760405162461bcd60e51b815260040161105f90614ce2565b60098290556040518281527ff060ec4074aa2bff6c27e525b53730a571906fbb232158fb0010de0618b7dcec90602001611854565b60008060015b6001600160a01b0385166000908152600d60205260409020548111611bd357611bb5858260008711611baf574261245f565b8661245f565b611bbf9083614d1b565b915080611bcb81614d33565b915050611b7d565b509392505050565b60006111fa82600061457e565b6006546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b158015611c2c57600080fd5b505afa158015611c40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c649190614dd2565b905090565b600160009054906101000a90046001600160a01b03166001600160a01b0316630fe175bb6040518163ffffffff1660e01b815260040160206040518083038186803b158015611cb757600080fd5b505afa158015611ccb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cef9190614c86565b6001546001600160a01b03161580611d845750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f690611d349084903390600401614ca9565b60206040518083038186803b158015611d4c57600080fd5b505afa158015611d60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d849190614cc5565b611da05760405162461bcd60e51b815260040161105f90614ce2565b60008311611dc05760405162461bcd60e51b815260040161105f90614deb565b600083815260026020908152604091829020805460ff19168515159081179091558251868152918201527f64b2c7c9023bdf999ad30ed3c65e970a3c40cee2783eba919fd23b7ff1d3618191016116c6565b600160009054906101000a90046001600160a01b03166001600160a01b0316630fe175bb6040518163ffffffff1660e01b815260040160206040518083038186803b158015611e6057600080fd5b505afa158015611e74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e989190614c86565b6001546001600160a01b03161580611f2d5750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f690611edd9084903390600401614ca9565b60206040518083038186803b158015611ef557600080fd5b505afa158015611f09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f2d9190614cc5565b611f495760405162461bcd60e51b815260040161105f90614ce2565b816005600086815260200190815260200160002084604051611f6b9190614e11565b9081526020016040518091039020819055507f054372fb4b28a093b83067aab525d4f07b8be4c06115990935f2c52e6d2258d48484846040516119fd93929190614e2d565b600160009054906101000a90046001600160a01b03166001600160a01b0316637c7c7c3c6040518163ffffffff1660e01b815260040160206040518083038186803b158015611ffe57600080fd5b505afa158015612012573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120369190614c86565b6001546001600160a01b031615806120cb5750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f69061207b9084903390600401614ca9565b60206040518083038186803b15801561209357600080fd5b505afa1580156120a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120cb9190614cc5565b6120e75760405162461bcd60e51b815260040161105f90614ce2565b6127108211156121295760405162461bcd60e51b815260206004820152600d60248201526c696e76616c69642076616c756560981b604482015260640161105f565b600a8290556040518281527f774b9fb928c71ca72bafa8771a63e9d00ea63b021cfd8cdc2ce4f003094c5d5890602001611854565b336000908152600c602052604081205460ff166121aa5760405162461bcd60e51b815260206004820152600a6024820152696e6f207365727669636560b01b604482015260640161105f565b60008381526002602052604090205460ff166121d85760405162461bcd60e51b815260040161105f90614deb565b6001600160a01b0384166000908152600d60205260408120546121fc906001614d1b565b9050600061220a868361118a565b9050600854600161221b9190614d1b565b6008556040518590601090612231908490614e11565b908152602001604051809103902081905550836011826040516122549190614e11565b908152602001604051809103902081905550836012826040516122779190614e11565b9081526040805160209281900383019020929092556001600160a01b0388166000908152600d90915220546122ad906001614d1b565b6001600160a01b0387166000908152600d6020908152604080832093909355600f8152828220888352905220546122e5906001614d1b565b6001600160a01b0387166000818152600f602090815260408083208a845282529182902093909355805188815292830185905282018690529033907f8d0c41be72ed32afe2338178b0bca6812741dbe490039b1fc3b9d1635914d04f9060600160405180910390a350949350505050565b6001546000906001600160a01b031615806123ee5750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f69061239e9084903390600401614ca9565b60206040518083038186803b1580156123b657600080fd5b505afa1580156123ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ee9190614cc5565b61240a5760405162461bcd60e51b815260040161105f90614ce2565b50600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000601061243b848461118a565b6040516124489190614e11565b908152602001604051809103902054905092915050565b60008061246c858561118a565b905060006010826040516124809190614e11565b908152602001604051809103902054905060006013836040516124a39190614e11565b908152602001604051809103902054600014156124de576011836040516124ca9190614e11565b9081526020016040518091039020546124fe565b6013836040516124ee9190614e11565b9081526020016040518091039020545b905060006011846040516125129190614e11565b908152602001604051809103902054905061252d88886126be565b61253e576000945050505050611183565b612548888861390b565b1561255a576000945050505050611183565b4286111561256f576000945050505050611183565b818611612583576000945050505050611183565b6000603c6125918389614d72565b61259b9190614dbe565b905060006125ba6125ab86611bdb565b6125b4876113ce565b846114e8565b90508315612604576000603c6125d08587614d72565b6125da9190614dbe565b905060006125f36125ea88611bdb565b6125b4896113ce565b90506125ff8184614d72565b925050505b60006126118b8b8b613b9a565b905061261d8183614d1b565b9b9a5050505050505050505050565b6001600160a01b0382166000908152600e602052604081205461264f8484611b77565b6111839190614d72565b6000806010612668868661118a565b6040516126759190614e11565b9081526020016040518091039020549050600061269386868661245f565b905061269e82614408565b6126a783613e1a565b6115209083614d89565b600061118383834261245f565b60008060126126cd858561118a565b6040516126da9190614e11565b90815260200160405180910390205411905092915050565b60006111fa82600961457e565b600160009054906101000a90046001600160a01b03166001600160a01b0316637c7c7c3c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561274d57600080fd5b505afa158015612761573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127859190614c86565b6001546001600160a01b0316158061281a5750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f6906127ca9084903390600401614ca9565b60206040518083038186803b1580156127e257600080fd5b505afa1580156127f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061281a9190614cc5565b6128365760405162461bcd60e51b815260040161105f90614ce2565b6001600160a01b03821661284957600080fd5b600b80546001600160a01b0319166001600160a01b0384169081179091556040519081527fd649da8f6092116f86ea4e5139de0b75ad371d823918d16368ba3ff09a5cbc9f90602001611854565b600061118360106128a8858561118a565b6040516128b59190614e11565b90815260200160405180910390205461415d565b60006128d583836126be565b80156128e857506128e6838361390b565b155b801561118357506128f98383614415565b159392505050565b60006111fa82600761457e565b60075460009081906001600160a01b0316331461292b573361292d565b325b9050600061293b828761118a565b9050600060108260405161294f9190614e11565b908152602001604051809103902054905060006013836040516129729190614e11565b908152602001604051809103902054600014156129ad576011836040516129999190614e11565b9081526020016040518091039020546129cd565b6013836040516129bd9190614e11565b9081526020016040518091039020545b90506129d984896126be565b612a145760405162461bcd60e51b815260206004820152600c60248201526b191bd95cdb9d08195e1a5cdd60a21b604482015260640161105f565b612a1e848961390b565b15612a5a5760405162461bcd60e51b815260206004820152600c60248201526b1b9bd91948195e1c1a5c995960a21b604482015260640161105f565b612a648489613897565b15612a9c5760405162461bcd60e51b8152602060048201526008602482015267706173742064756560c01b604482015260640161105f565b42871115612adc5760405162461bcd60e51b815260206004820152600d60248201526c06261642074696d657374616d7609c1b604482015260640161105f565b86612ae982610384614d1b565b10612b215760405162461bcd60e51b81526020600482015260086024820152673a37b79039b7b7b760c11b604482015260640161105f565b6000612b2e858a8a61245f565b905060008111612b6c5760405162461bcd60e51b81526020600482015260096024820152681b9bc81c995dd85c9960ba1b604482015260640161105f565b6006546040516370a0823160e01b815230600482015282916001600160a01b0316906370a082319060240160206040518083038186803b158015612baf57600080fd5b505afa158015612bc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612be79190614dd2565b1015612c245760405162461bcd60e51b815260206004820152600c60248201526b6f7665722062616c616e636560a01b604482015260640161105f565b6000612c2f84614408565b612c3885613e1a565b612c429084614d89565b612c4c9190614dbe565b905080341015612c6e5760405162461bcd60e51b815260040161105f90614e56565b88601386604051612c7f9190614e11565b9081526040805160209281900383018120939093558c83529082018490526001600160a01b038816917f987d620f307ff6b94d58743cb7a7509f24071586a77759b77c2d4e29f75a2f9a910160405180910390a2336000908152600e602052604090205415612d6157336000908152600e6020526040902054821015612d3457336000908152600e6020526040902054612d1a908390614d72565b336000908152600e60205260408120919091559150612d61565b336000908152600e6020526040902054612d4e9083614d72565b336000908152600e602052604081205591505b8115612e7f576001600160a01b03881615612ddd576040516330d6a97560e01b81526001600160a01b038781166004830152602482018490528916906330d6a97590604401600060405180830381600087803b158015612dc057600080fd5b505af1158015612dd4573d6000803e3d6000fd5b50505050612e7f565b60065460405163a9059cbb60e01b81526001600160a01b038881166004830152602482018590529091169063a9059cbb90604401602060405180830381600087803b158015612e2b57600080fd5b505af1158015612e3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e639190614cc5565b612e7f5760405162461bcd60e51b815260040161105f90614e7b565b600b54612e95906001600160a01b031682614609565b612e9d614786565b8015612ea857508034115b15612ec057612ec033612ebb8334614d72565b614609565b9998505050505050505050565b6000612ed883611534565b90506000612ee58461357a565b90506000612ef285611200565b60008681526002602052604090205490915060ff16612f235760405162461bcd60e51b815260040161105f90614deb565b6009541580612f425750600954336000908152600d6020526040902054105b612f7b5760405162461bcd60e51b815260206004820152600a6024820152691bdd995c881b1a5b5a5d60b21b604482015260640161105f565b801580612fa15750336000908152600f6020908152604080832088845290915290205481115b612fda5760405162461bcd60e51b815260206004820152600a6024820152691bdd995c881b1a5b5a5d60b21b604482015260640161105f565b82341015612ffa5760405162461bcd60e51b815260040161105f90614e56565b336000908152600d6020526040812054613015906001614d1b565b90506000613023338361118a565b905060085460016130349190614d1b565b600855604051879060109061304a908490614e11565b9081526020016040518091039020819055504260118260405161306d9190614e11565b908152602001604051809103902081905550426012826040516130909190614e11565b908152604080516020928190038301902092909255336000908152600d90915220546130bd906001614d1b565b336000908152600d6020908152604080832093909355600f81528282208a8352905220546130ec906001614d1b565b336000818152600f602090815260408083208c84528252918290209390935580518a815292830185905288151590830152426060830152907f450a067d57712752555ba8fac2ec18dd15718b07539357bc1578ee837ef1422a9060800160405180910390a285156131b05783613162334261262c565b10156131805760405162461bcd60e51b815260040161105f90614d4e565b336000908152600e602052604090205461319b908590614d1b565b336000908152600e6020526040902055613349565b6000612710600a54866131c39190614d89565b6131cd9190614dbe565b9050801561327f57600654600b546040516323b872dd60e01b81523360048201526001600160a01b039182166024820152604481018490529116906323b872dd90606401602060405180830381600087803b15801561322b57600080fd5b505af115801561323f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132639190614cc5565b61327f5760405162461bcd60e51b815260040161105f90614e7b565b80851115613347576006546001600160a01b03166323b872dd33306132a4858a614d72565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401602060405180830381600087803b1580156132f357600080fd5b505af1158015613307573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061332b9190614cc5565b6133475760405162461bcd60e51b815260040161105f90614e7b565b505b600b5461335f906001600160a01b031686614609565b843411156133755761337533612ebb8734614d72565b50505050505050565b600160009054906101000a90046001600160a01b03166001600160a01b0316637c7c7c3c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156133cc57600080fd5b505afa1580156133e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134049190614c86565b6001546001600160a01b031615806134995750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f6906134499084903390600401614ca9565b60206040518083038186803b15801561346157600080fd5b505afa158015613475573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134999190614cc5565b6134b55760405162461bcd60e51b815260040161105f90614ce2565b600082116134c257600080fd5b6006546040516323b872dd60e01b8152336004820152306024820152604481018490526001600160a01b03909116906323b872dd90606401602060405180830381600087803b15801561351457600080fd5b505af1158015613528573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061354c9190614cc5565b6135685760405162461bcd60e51b815260040161105f90614e7b565b5050565b6000601261243b848461118a565b60006111fa82600261457e565b600160009054906101000a90046001600160a01b03166001600160a01b0316637c7c7c3c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156135d557600080fd5b505afa1580156135e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061360d9190614c86565b6001546001600160a01b031615806136a25750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f6906136529084903390600401614ca9565b60206040518083038186803b15801561366a57600080fd5b505afa15801561367e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136a29190614cc5565b6136be5760405162461bcd60e51b815260040161105f90614ce2565b50600680546001600160a01b0319166001600160a01b0392909216919091179055565b6000806136ee338461118a565b905060006010826040516137029190614e11565b9081526020016040518091039020549050600061371e8261415d565b905061372a33866128c9565b6137615760405162461bcd60e51b815260206004820152600860248201526763616e742070617960c01b604482015260640161105f565b803410156137815760405162461bcd60e51b815260040161105f90614e56565b61378a82612901565b60128460405161379a9190614e11565b9081526020016040518091039020546137b39190614d1b565b6012846040516137c39190614e11565b908152602001604051809103902081905550336001600160a01b03167f1ff60751a354563b8db02f735046d6cecdd1ec33b27b453a7925da806b529adb83876012876040516138129190614e11565b9081526040519081900360200181205461383e9392919283526020830191909152604082015260600190565b60405180910390a2600b5461385c906001600160a01b031682614609565b613864614786565b801561386f57508034115b156138825761388233612ebb8334614d72565b949350505050565b60006111fa82600861457e565b6000806138a4848461118a565b905060006010826040516138b89190614e11565b908152602001604051809103902054905060006012836040516138db9190614e11565b90815260200160405180910390205490506138f582612901565b6138ff9082614d1b565b42119695505050505050565b600080613918848461118a565b9050600060108260405161392c9190614e11565b9081526020016040518091039020549050600060128360405161394f9190614e11565b9081526020016040518091039020549050806000141561397557600193505050506111fa565b61397e8261388a565b61398783612901565b6139919083614d1b565b6138ff9190614d1b565b600160009054906101000a90046001600160a01b03166001600160a01b0316637c7c7c3c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156139e957600080fd5b505afa1580156139fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a219190614c86565b6001546001600160a01b03161580613ab65750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f690613a669084903390600401614ca9565b60206040518083038186803b158015613a7e57600080fd5b505afa158015613a92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ab69190614cc5565b613ad25760405162461bcd60e51b815260040161105f90614ce2565b60065460405163095ea7b360e01b81526001600160a01b038581166004830152602482018590529091169063095ea7b390604401602060405180830381600087803b158015613b2057600080fd5b505af1158015613b34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b589190614cc5565b613b955760405162461bcd60e51b815260206004820152600e60248201526d185c1c1c9bdd994819985a5b195960921b604482015260640161105f565b505050565b6007546000906001600160a01b0316613bb557506000611183565b6000613bc1858561118a565b90506000601082604051613bd59190614e11565b90815260200160405180910390205490506000601383604051613bf89190614e11565b90815260200160405180910390205460001415613c3357601183604051613c1f9190614e11565b908152602001604051809103902054613c53565b601383604051613c439190614e11565b9081526020016040518091039020545b6007546040516394d14a9b60e01b81526001600160a01b038a811660048301526001600160801b038a166024830152306044830152929350600092909116906394d14a9b9060640160006040518083038186803b158015613cb357600080fd5b505afa158015613cc7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613cef9190810190614ea4565b9050604051602001613d0c90602080825260009082015260400190565b6040516020818303038152906040528051906020012081604051602001613d3391906148e5565b604051602081830303815290604052805190602001201415613d5c576000945050505050611183565b6000613d6884836140c0565b905060008111613d79576000612ec0565b600754604051632034eb5160e01b81526001600160a01b038b811660048301526001600160801b038b16602483015260448201869052606482018a90526084820184905290911690632034eb519060a40160206040518083038186803b158015613de257600080fd5b505afa158015613df6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ec09190614dd2565b60006111fa82600561457e565b60026000908155338152600d6020526040902054613e725760405162461bcd60e51b81526020600482015260086024820152676e6f206e6f64657360c01b604482015260640161105f565b34600083613e81576001613e83565b835b90506000808411613ea357336000908152600d6020526040902054613ea5565b835b9050815b818111613f1057613eba33826128c9565b613ec357613efe565b60008411613ee35760405162461bcd60e51b815260040161105f90614d4e565b6000613eee826136e1565b9050613efa8186614d72565b9450505b80613f0881614d33565b915050613ea9565b508215613f2157613f213384614609565b50506001600055505050565b600160009054906101000a90046001600160a01b03166001600160a01b0316630fe175bb6040518163ffffffff1660e01b815260040160206040518083038186803b158015613f7b57600080fd5b505afa158015613f8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fb39190614c86565b6001546001600160a01b031615806140485750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f690613ff89084903390600401614ca9565b60206040518083038186803b15801561401057600080fd5b505afa158015614024573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140489190614cc5565b6140645760405162461bcd60e51b815260040161105f90614ce2565b6001600160a01b0383166000818152600c6020908152604091829020805460ff19168615159081179091558251938452908301527fea782fa1fcb250a935b6bf028374e06a580a12523d2befc1c2254a3cd3ef378091016116c6565b60008281526005602052604080822090518291906140df908590614e11565b90815260200160405180910390205411614140576000805260056020526040517f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746bc9061412c908490614e11565b908152602001604051809103902054611183565b600083815260056020526040908190209051612448908490614e11565b60006111fa82600461457e565b600160009054906101000a90046001600160a01b03166001600160a01b0316637c7c7c3c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156141b857600080fd5b505afa1580156141cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141f09190614c86565b6001546001600160a01b031615806142855750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f6906142359084903390600401614ca9565b60206040518083038186803b15801561424d57600080fd5b505afa158015614261573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142859190614cc5565b6142a15760405162461bcd60e51b815260040161105f90614ce2565b600082116142ae57600080fd5b6006546040516370a0823160e01b815230600482015283916001600160a01b0316906370a082319060240160206040518083038186803b1580156142f157600080fd5b505afa158015614305573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143299190614dd2565b10156143665760405162461bcd60e51b815260206004820152600c60248201526b6f7665722062616c616e636560a01b604482015260640161105f565b60065460405163a9059cbb60e01b81526001600160a01b038581166004830152602482018590529091169063a9059cbb90604401602060405180830381600087803b1580156143b457600080fd5b505af11580156143c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143ec9190614cc5565b613b955760405162461bcd60e51b815260040161105f90614e7b565b60006111fa82600661457e565b600080614422848461118a565b905060006010826040516144369190614e11565b908152602001604051809103902054905060006012836040516144599190614e11565b9081526020016040518091039020549050600061447583612901565b90506000614482846126f2565b61448c9083614d89565b6144969042614d1b565b9050806144a38385614d1b565b101598975050505050505050565b60008080846144c15760016144c3565b845b905060008085116144ec576001600160a01b0388166000908152600d60205260409020546144ee565b845b9050815b8181116145715760006145148a8360008c1161450e574261245f565b8b61245f565b9050801561455e5760006145288b8461242d565b905061453381614408565b61453c82613e1a565b6145469084614d89565b6145509190614dbe565b61455a9087614d1b565b9550505b508061456981614d33565b9150506144f2565b5091979650505050505050565b60008281526003602052604081205460ff1680156145b45750600083815260046020908152604080832085845290915290205415155b6145eb5760008281527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ec6020526040902054611183565b50600091825260046020908152604080842092845291905290205490565b804710156146505760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b604482015260640161105f565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461469d576040519150601f19603f3d011682016040523d82523d6000602084013e6146a2565b606091505b5050905080613b955760405162461bcd60e51b815260206004820152600b60248201526a1cd95b990819985a5b195960aa1b604482015260640161105f565b6000631f5405008211156146f757631f54050091505b8161470b5750670de0b6b3a76400006111fa565b670de0b6b3a764000083835b600181111561477c5761472b600282614f1b565b61474d57614739828361479c565b9150614746600282614dbe565b9050614717565b614757828461479c565b9250614763828361479c565b91506002614772600183614d72565b6147469190614dbe565b61152a828461479c565b60008054600214158015611c6457505033321490565b6000806147a98385614d89565b9050670de0b6b3a76400006147bf600282614dbe565b6147c99083614d1b565b6138829190614dbe565b6001600160a01b03811681146147e857600080fd5b50565b600080604083850312156147fe57600080fd5b8235614809816147d3565b946020939093013593505050565b60008060006060848603121561482c57600080fd5b8335614837816147d3565b92506020840135614847816147d3565b929592945050506040919091013590565b60008060006060848603121561486d57600080fd5b8335614878816147d3565b95602085013595506040909401359392505050565b60005b838110156148a8578181015183820152602001614890565b838111156110f35750506000910152565b600081518084526148d181602086016020860161488d565b601f01601f19169290920160200192915050565b60208152600061118360208301846148b9565b60006020828403121561490a57600080fd5b5035919050565b60008060006060848603121561492657600080fd5b8335614931816147d3565b92506020840135614941816147d3565b91506040840135614951816147d3565b809150509250925092565b6000806000806080858703121561497257600080fd5b843593506020850135614984816147d3565b93969395505050506040820135916060013590565b6000602082840312156149ab57600080fd5b8135611183816147d3565b6000806000606084860312156149cb57600080fd5b505081359360208301359350604090920135919050565b80151581146147e857600080fd5b60008060408385031215614a0357600080fd5b823591506020830135614a15816149e2565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614a5f57614a5f614a20565b604052919050565b600067ffffffffffffffff821115614a8157614a81614a20565b50601f01601f191660200190565b6000614aa2614a9d84614a67565b614a36565b9050828152838383011115614ab657600080fd5b828260208301376000602084830101529392505050565b600082601f830112614ade57600080fd5b61118383833560208501614a8f565b60008060408385031215614b0057600080fd5b82359150602083013567ffffffffffffffff811115614b1e57600080fd5b614b2a85828601614acd565b9150509250929050565b600080600060608486031215614b4957600080fd5b83359250602084013567ffffffffffffffff811115614b6757600080fd5b614b7386828701614acd565b925050604084013590509250925092565b600060208284031215614b9657600080fd5b813567ffffffffffffffff811115614bad57600080fd5b8201601f81018413614bbe57600080fd5b61388284823560208401614a8f565b600080600060608486031215614be257600080fd5b83359250602084013591506040840135614951816147d3565b60008060408385031215614c0e57600080fd5b50508035926020909101359150565b60008060408385031215614c3057600080fd5b8235614c3b816147d3565b91506020830135614a15816149e2565b60008060008060808587031215614c6157600080fd5b8435614c6c816147d3565b966020860135965060408601359560600135945092505050565b600060208284031215614c9857600080fd5b815160ff8116811461118357600080fd5b60ff9290921682526001600160a01b0316602082015260400190565b600060208284031215614cd757600080fd5b8151611183816149e2565b6020808252600990820152686e6f2061636365737360b81b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60008219821115614d2e57614d2e614d05565b500190565b6000600019821415614d4757614d47614d05565b5060010190565b6020808252600a90820152690dcdee840cadcdeeaced60b31b604082015260600190565b600082821015614d8457614d84614d05565b500390565b6000816000190483118215151615614da357614da3614d05565b500290565b634e487b7160e01b600052601260045260246000fd5b600082614dcd57614dcd614da8565b500490565b600060208284031215614de457600080fd5b5051919050565b6020808252600c908201526b696e76616c6964207479706560a01b604082015260600190565b60008251614e2381846020870161488d565b9190910192915050565b838152606060208201526000614e4660608301856148b9565b9050826040830152949350505050565b6020808252600b908201526a696e76616c69642066656560a81b604082015260600190565b6020808252600f908201526e1d1c985b9cd9995c8819985a5b1959608a1b604082015260600190565b600060208284031215614eb657600080fd5b815167ffffffffffffffff811115614ecd57600080fd5b8201601f81018413614ede57600080fd5b8051614eec614a9d82614a67565b818152856020838501011115614f0157600080fd5b614f1282602083016020860161488d565b95945050505050565b600082614f2a57614f2a614da8565b50069056fea264697066735822122000b507d9b6d3ec2a4d5bfd94f37852e762e6137e0804b8bbd2449b11ac1a67ba64736f6c63430008090033

Deployed Bytecode

0x6080604052600436106104895760003560e01c80639548f1e611610255578063c8f064ec11610144578063e79ae18b116100c1578063f232ee3711610085578063f232ee3714610e7e578063f3fef3a314610e93578063f5474cb014610eb3578063f9df21e714610ed3578063fade29de14610ef3578063fefe2f5814610f1357600080fd5b8063e79ae18b14610db9578063e94d59dc14610df1578063ea97bba614610e11578063eaace4cc14610e49578063eaffeddc14610e5e57600080fd5b8063dd811fff11610108578063dd811fff14610d31578063de20d47a14610d51578063e0b5485914610d71578063e2ca3c3a14610d84578063e5f4f66714610da457600080fd5b8063c8f064ec14610c8e578063d1c25be314610ca3578063d2d7b21414610cc3578063d7feb2fe14610cd9578063dc2e86e914610d1157600080fd5b8063ac44ff31116101d2578063bbcd5bbe11610196578063bbcd5bbe14610bfb578063c290d69114610c1b578063c415b95c14610c2e578063c548201114610c4e578063c741643714610c6e57600080fd5b8063ac44ff3114610b75578063afc9a71b14610b88578063b6b55f2514610b9b578063b7fef4ce14610bbb578063bbbf0f6614610bdb57600080fd5b8063a42dce8011610219578063a42dce8014610ac8578063a5ea985d14610ae8578063a77e282514610b08578063aa81ce3e14610b35578063aadea3f314610b5557600080fd5b80639548f1e614610a325780639592d42414610a52578063965d61b914610a685780639daf08c014610a88578063a052058114610aa857600080fd5b80635041ae2b1161037c5780636fdd1ff1116102f9578063855f261e116102bd578063855f261e1461094a5780638ccf7f23146109825780638ecddc05146109b25780638eda065f146109d25780639145e391146109f2578063939c6bfb14610a1257600080fd5b80636fdd1ff11461089257806373d70677146108b257806378a76066146108d25780637a0b92551461090a57806381e79c0c1461092a57600080fd5b8063555d3e6311610340578063555d3e63146107e5578063572887b01461081d5780635e42b4551461083d57806361a3aa8e1461085257806363a441021461087257600080fd5b80635041ae2b1461073b57806350d0eed014610750578063528402791461076557806353663f7b1461078557806355079ddd146107c557600080fd5b806327bee7471161040a5780634608482d116103ce5780634608482d146106725780634de740ba146106925780634df78d5f146106b25780634ff63422146106d25780634ffbcc0c1461071b57600080fd5b806327bee747146105e557806331ed56f9146105fb578063342ec83d146106105780633bc16d701461063d57806341e666911461065257600080fd5b806311d7096d1161045157806311d7096d1461055d578063184b95591461057d57806319ba32631461059d57806321d2ab8a146105bd5780632749bf4f146105d257600080fd5b806301bd2f811461048e57806301e33667146104d9578063030fca67146104fb5780630c056e411461051b5780630c931cd014610548575b600080fd5b34801561049a57600080fd5b506104c66104a93660046147eb565b600f60209081526000928352604080842090915290825290205481565b6040519081526020015b60405180910390f35b3480156104e557600080fd5b506104f96104f4366004614817565b610f28565b005b34801561050757600080fd5b506104c6610516366004614858565b6110f9565b34801561052757600080fd5b5061053b6105363660046147eb565b61118a565b6040516104d091906148e5565b34801561055457600080fd5b506104c6600181565b34801561056957600080fd5b506104c66105783660046148f8565b611200565b34801561058957600080fd5b506104f9610598366004614911565b61120d565b3480156105a957600080fd5b506104c66105b83660046148f8565b6113ce565b3480156105c957600080fd5b506104c6600881565b6104f96105e036600461495c565b6113db565b3480156105f157600080fd5b506104c660095481565b34801561060757600080fd5b506104c6600081565b34801561061c57600080fd5b506104c661062b366004614999565b600e6020526000908152604090205481565b34801561064957600080fd5b506104c6600a81565b34801561065e57600080fd5b506104c661066d3660046149b6565b6114e8565b34801561067e57600080fd5b506104c661068d3660046148f8565b611534565b34801561069e57600080fd5b506104f96106ad3660046149f0565b611541565b3480156106be57600080fd5b506104f96106cd366004614999565b6116d3565b3480156106de57600080fd5b506104c66106ed366004614aed565b6005602090815260009283526040909220815180830184018051928152908401929093019190912091525481565b34801561072757600080fd5b506104f96107363660046149b6565b611860565b34801561074757600080fd5b506104c6600681565b34801561075c57600080fd5b506104c6600781565b34801561077157600080fd5b506104f96107803660046148f8565b611a0b565b34801561079157600080fd5b506107b56107a03660046148f8565b60036020526000908152604090205460ff1681565b60405190151581526020016104d0565b3480156107d157600080fd5b506104c66107e03660046147eb565b611b77565b3480156107f157600080fd5b50600154610805906001600160a01b031681565b6040516001600160a01b0390911681526020016104d0565b34801561082957600080fd5b506104c66108383660046148f8565b611bdb565b34801561084957600080fd5b506104c6611be8565b34801561085e57600080fd5b506104f961086d3660046149f0565b611c69565b34801561087e57600080fd5b506104f961088d366004614b34565b611e12565b34801561089e57600080fd5b506104f96108ad3660046148f8565b611fb0565b3480156108be57600080fd5b506104c66108cd366004614858565b61215e565b3480156108de57600080fd5b506104c66108ed366004614b84565b805160208183018101805160108252928201919093012091525481565b34801561091657600080fd5b506104f9610925366004614999565b612356565b34801561093657600080fd5b506104c66109453660046147eb565b61242d565b34801561095657600080fd5b506104c6610965366004614b84565b805160208183018101805160138252928201919093012091525481565b34801561098e57600080fd5b506107b561099d3660046148f8565b60026020526000908152604090205460ff1681565b3480156109be57600080fd5b506104c66109cd366004614858565b61245f565b3480156109de57600080fd5b506104c66109ed3660046147eb565b61262c565b3480156109fe57600080fd5b506104c6610a0d366004614858565b612659565b348015610a1e57600080fd5b506104c6610a2d3660046147eb565b6126b1565b348015610a3e57600080fd5b50600754610805906001600160a01b031681565b348015610a5e57600080fd5b506104c660085481565b348015610a7457600080fd5b50600654610805906001600160a01b031681565b348015610a9457600080fd5b506107b5610aa33660046147eb565b6126be565b348015610ab457600080fd5b506104c6610ac33660046148f8565b6126f2565b348015610ad457600080fd5b506104f9610ae3366004614999565b6126ff565b348015610af457600080fd5b506104c6610b033660046147eb565b612897565b348015610b1457600080fd5b506104c6610b23366004614999565b600d6020526000908152604090205481565b348015610b4157600080fd5b506107b5610b503660046147eb565b6128c9565b348015610b6157600080fd5b506104c6610b703660046148f8565b612901565b6104c6610b83366004614bcd565b61290e565b6104f9610b963660046149f0565b612ecd565b348015610ba757600080fd5b506104f9610bb63660046148f8565b61337e565b348015610bc757600080fd5b506104c6610bd63660046147eb565b61356c565b348015610be757600080fd5b506104c6610bf63660046148f8565b61357a565b348015610c0757600080fd5b506104f9610c16366004614999565b613587565b6104c6610c293660046148f8565b6136e1565b348015610c3a57600080fd5b50600b54610805906001600160a01b031681565b348015610c5a57600080fd5b506104c6610c693660046148f8565b61388a565b348015610c7a57600080fd5b506107b5610c893660046147eb565b613897565b348015610c9a57600080fd5b506104c6600481565b348015610caf57600080fd5b506107b5610cbe3660046147eb565b61390b565b348015610ccf57600080fd5b506104c6600a5481565b348015610ce557600080fd5b506104c6610cf4366004614b84565b805160208183018101805160128252928201919093012091525481565b348015610d1d57600080fd5b506104f9610d2c3660046147eb565b61399b565b348015610d3d57600080fd5b506104c6610d4c366004614858565b613b9a565b348015610d5d57600080fd5b506104c6610d6c3660046148f8565b613e1a565b6104f9610d7f366004614bfb565b613e27565b348015610d9057600080fd5b506104f9610d9f366004614c1d565b613f2d565b348015610db057600080fd5b506104c6600281565b348015610dc557600080fd5b506104c6610dd4366004614b84565b805160208183018101805160118252928201919093012091525481565b348015610dfd57600080fd5b506104c6610e0c366004614aed565b6140c0565b348015610e1d57600080fd5b506104c6610e2c366004614bfb565b600460209081526000928352604080842090915290825290205481565b348015610e5557600080fd5b506104c6600381565b348015610e6a57600080fd5b506104c6610e793660046148f8565b61415d565b348015610e8a57600080fd5b506104c6600981565b348015610e9f57600080fd5b506104f9610eae3660046147eb565b61416a565b348015610ebf57600080fd5b506104c6610ece3660046148f8565b614408565b348015610edf57600080fd5b506107b5610eee3660046147eb565b614415565b348015610eff57600080fd5b506104c6610f0e366004614c4b565b6144b1565b348015610f1f57600080fd5b506104c6600581565b600160009054906101000a90046001600160a01b03166001600160a01b0316637c7c7c3c6040518163ffffffff1660e01b815260040160206040518083038186803b158015610f7657600080fd5b505afa158015610f8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fae9190614c86565b6001546001600160a01b031615806110435750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f690610ff39084903390600401614ca9565b60206040518083038186803b15801561100b57600080fd5b505afa15801561101f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110439190614cc5565b6110685760405162461bcd60e51b815260040161105f90614ce2565b60405180910390fd5b60405163a9059cbb60e01b81526001600160a01b0384811660048301526024820184905285169063a9059cbb90604401602060405180830381600087803b1580156110b257600080fd5b505af11580156110c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ea9190614cc5565b6110f357600080fd5b50505050565b600080808461110957600161110b565b845b90506000808511611134576001600160a01b0387166000908152600d6020526040902054611136565b845b9050815b81811161117c5761114b88826128c9565b1561116a5761115d610e79898361242d565b6111679085614d1b565b93505b8061117481614d33565b91505061113a565b5091925050505b9392505050565b60606000826111bc576001600160a01b0384166000908152600d60205260409020546111b7906001614d1b565b6111be565b825b6040516bffffffffffffffffffffffff19606087901b166020820152603481018290529091506054016040516020818303038152906040529150505b92915050565b60006111fa82600a61457e565b600160009054906101000a90046001600160a01b03166001600160a01b0316637c7c7c3c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561125b57600080fd5b505afa15801561126f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112939190614c86565b6001546001600160a01b031615806113285750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f6906112d89084903390600401614ca9565b60206040518083038186803b1580156112f057600080fd5b505afa158015611304573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113289190614cc5565b6113445760405162461bcd60e51b815260040161105f90614ce2565b6001600160a01b0382166113875760405162461bcd60e51b815260206004820152600a6024820152696e6f206164647265737360b01b604482015260640161105f565b600680546001600160a01b038087166001600160a01b03199283161790925560078054868416908316179055600b8054928516929091169190911790556110f36001600055565b60006111fa82600161457e565b60026000908155338152600d60205260409020546114265760405162461bcd60e51b81526020600482015260086024820152676e6f206e6f64657360c01b604482015260640161105f565b34600083611435576001611437565b835b9050600080841161145757336000908152600d6020526040902054611459565b835b9050815b8181116114c957600061147133838b61245f565b905080156114b657600085116114995760405162461bcd60e51b815260040161105f90614d4e565b60006114a6838b8b61290e565b90506114b28187614d72565b9550505b50806114c181614d33565b91505061145d565b5082156114da576114da3384614609565b505060016000555050505050565b6000806114f584846146e1565b9050600061150b82670de0b6b3a7640000614d72565b9050670de0b6b3a76400006115208288614d89565b61152a9190614dbe565b9695505050505050565b60006111fa82600361457e565b600160009054906101000a90046001600160a01b03166001600160a01b0316630fe175bb6040518163ffffffff1660e01b815260040160206040518083038186803b15801561158f57600080fd5b505afa1580156115a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115c79190614c86565b6001546001600160a01b0316158061165c5750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f69061160c9084903390600401614ca9565b60206040518083038186803b15801561162457600080fd5b505afa158015611638573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061165c9190614cc5565b6116785760405162461bcd60e51b815260040161105f90614ce2565b600083815260036020908152604091829020805460ff19168515159081179091558251868152918201527f43310f1a48ae0abe7aa4426ad65f06014365dfb499aaeafa1678bba75ab032ff91015b60405180910390a1505050565b600160009054906101000a90046001600160a01b03166001600160a01b0316630fe175bb6040518163ffffffff1660e01b815260040160206040518083038186803b15801561172157600080fd5b505afa158015611735573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117599190614c86565b6001546001600160a01b031615806117ee5750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f69061179e9084903390600401614ca9565b60206040518083038186803b1580156117b657600080fd5b505afa1580156117ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117ee9190614cc5565b61180a5760405162461bcd60e51b815260040161105f90614ce2565b600780546001600160a01b0319166001600160a01b0384169081179091556040519081527fa30ea3596e6b0bf63d799ca3146166f9b51a9eb996ce58e022ef806c13e17ff0906020015b60405180910390a15050565b600160009054906101000a90046001600160a01b03166001600160a01b0316630fe175bb6040518163ffffffff1660e01b815260040160206040518083038186803b1580156118ae57600080fd5b505afa1580156118c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118e69190614c86565b6001546001600160a01b0316158061197b5750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f69061192b9084903390600401614ca9565b60206040518083038186803b15801561194357600080fd5b505afa158015611957573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061197b9190614cc5565b6119975760405162461bcd60e51b815260040161105f90614ce2565b6000848152600360209081526040808320805460ff191660011790556004825280832086845282529182902084905581518681529081018590529081018390527fb769bc1108ca077938f2f70329b1f983427891545696672e587358c37bb0187e906060015b60405180910390a150505050565b600160009054906101000a90046001600160a01b03166001600160a01b0316630fe175bb6040518163ffffffff1660e01b815260040160206040518083038186803b158015611a5957600080fd5b505afa158015611a6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a919190614c86565b6001546001600160a01b03161580611b265750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f690611ad69084903390600401614ca9565b60206040518083038186803b158015611aee57600080fd5b505afa158015611b02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b269190614cc5565b611b425760405162461bcd60e51b815260040161105f90614ce2565b60098290556040518281527ff060ec4074aa2bff6c27e525b53730a571906fbb232158fb0010de0618b7dcec90602001611854565b60008060015b6001600160a01b0385166000908152600d60205260409020548111611bd357611bb5858260008711611baf574261245f565b8661245f565b611bbf9083614d1b565b915080611bcb81614d33565b915050611b7d565b509392505050565b60006111fa82600061457e565b6006546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b158015611c2c57600080fd5b505afa158015611c40573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c649190614dd2565b905090565b600160009054906101000a90046001600160a01b03166001600160a01b0316630fe175bb6040518163ffffffff1660e01b815260040160206040518083038186803b158015611cb757600080fd5b505afa158015611ccb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cef9190614c86565b6001546001600160a01b03161580611d845750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f690611d349084903390600401614ca9565b60206040518083038186803b158015611d4c57600080fd5b505afa158015611d60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d849190614cc5565b611da05760405162461bcd60e51b815260040161105f90614ce2565b60008311611dc05760405162461bcd60e51b815260040161105f90614deb565b600083815260026020908152604091829020805460ff19168515159081179091558251868152918201527f64b2c7c9023bdf999ad30ed3c65e970a3c40cee2783eba919fd23b7ff1d3618191016116c6565b600160009054906101000a90046001600160a01b03166001600160a01b0316630fe175bb6040518163ffffffff1660e01b815260040160206040518083038186803b158015611e6057600080fd5b505afa158015611e74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e989190614c86565b6001546001600160a01b03161580611f2d5750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f690611edd9084903390600401614ca9565b60206040518083038186803b158015611ef557600080fd5b505afa158015611f09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f2d9190614cc5565b611f495760405162461bcd60e51b815260040161105f90614ce2565b816005600086815260200190815260200160002084604051611f6b9190614e11565b9081526020016040518091039020819055507f054372fb4b28a093b83067aab525d4f07b8be4c06115990935f2c52e6d2258d48484846040516119fd93929190614e2d565b600160009054906101000a90046001600160a01b03166001600160a01b0316637c7c7c3c6040518163ffffffff1660e01b815260040160206040518083038186803b158015611ffe57600080fd5b505afa158015612012573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120369190614c86565b6001546001600160a01b031615806120cb5750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f69061207b9084903390600401614ca9565b60206040518083038186803b15801561209357600080fd5b505afa1580156120a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120cb9190614cc5565b6120e75760405162461bcd60e51b815260040161105f90614ce2565b6127108211156121295760405162461bcd60e51b815260206004820152600d60248201526c696e76616c69642076616c756560981b604482015260640161105f565b600a8290556040518281527f774b9fb928c71ca72bafa8771a63e9d00ea63b021cfd8cdc2ce4f003094c5d5890602001611854565b336000908152600c602052604081205460ff166121aa5760405162461bcd60e51b815260206004820152600a6024820152696e6f207365727669636560b01b604482015260640161105f565b60008381526002602052604090205460ff166121d85760405162461bcd60e51b815260040161105f90614deb565b6001600160a01b0384166000908152600d60205260408120546121fc906001614d1b565b9050600061220a868361118a565b9050600854600161221b9190614d1b565b6008556040518590601090612231908490614e11565b908152602001604051809103902081905550836011826040516122549190614e11565b908152602001604051809103902081905550836012826040516122779190614e11565b9081526040805160209281900383019020929092556001600160a01b0388166000908152600d90915220546122ad906001614d1b565b6001600160a01b0387166000908152600d6020908152604080832093909355600f8152828220888352905220546122e5906001614d1b565b6001600160a01b0387166000818152600f602090815260408083208a845282529182902093909355805188815292830185905282018690529033907f8d0c41be72ed32afe2338178b0bca6812741dbe490039b1fc3b9d1635914d04f9060600160405180910390a350949350505050565b6001546000906001600160a01b031615806123ee5750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f69061239e9084903390600401614ca9565b60206040518083038186803b1580156123b657600080fd5b505afa1580156123ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123ee9190614cc5565b61240a5760405162461bcd60e51b815260040161105f90614ce2565b50600180546001600160a01b0319166001600160a01b0392909216919091179055565b6000601061243b848461118a565b6040516124489190614e11565b908152602001604051809103902054905092915050565b60008061246c858561118a565b905060006010826040516124809190614e11565b908152602001604051809103902054905060006013836040516124a39190614e11565b908152602001604051809103902054600014156124de576011836040516124ca9190614e11565b9081526020016040518091039020546124fe565b6013836040516124ee9190614e11565b9081526020016040518091039020545b905060006011846040516125129190614e11565b908152602001604051809103902054905061252d88886126be565b61253e576000945050505050611183565b612548888861390b565b1561255a576000945050505050611183565b4286111561256f576000945050505050611183565b818611612583576000945050505050611183565b6000603c6125918389614d72565b61259b9190614dbe565b905060006125ba6125ab86611bdb565b6125b4876113ce565b846114e8565b90508315612604576000603c6125d08587614d72565b6125da9190614dbe565b905060006125f36125ea88611bdb565b6125b4896113ce565b90506125ff8184614d72565b925050505b60006126118b8b8b613b9a565b905061261d8183614d1b565b9b9a5050505050505050505050565b6001600160a01b0382166000908152600e602052604081205461264f8484611b77565b6111839190614d72565b6000806010612668868661118a565b6040516126759190614e11565b9081526020016040518091039020549050600061269386868661245f565b905061269e82614408565b6126a783613e1a565b6115209083614d89565b600061118383834261245f565b60008060126126cd858561118a565b6040516126da9190614e11565b90815260200160405180910390205411905092915050565b60006111fa82600961457e565b600160009054906101000a90046001600160a01b03166001600160a01b0316637c7c7c3c6040518163ffffffff1660e01b815260040160206040518083038186803b15801561274d57600080fd5b505afa158015612761573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127859190614c86565b6001546001600160a01b0316158061281a5750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f6906127ca9084903390600401614ca9565b60206040518083038186803b1580156127e257600080fd5b505afa1580156127f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061281a9190614cc5565b6128365760405162461bcd60e51b815260040161105f90614ce2565b6001600160a01b03821661284957600080fd5b600b80546001600160a01b0319166001600160a01b0384169081179091556040519081527fd649da8f6092116f86ea4e5139de0b75ad371d823918d16368ba3ff09a5cbc9f90602001611854565b600061118360106128a8858561118a565b6040516128b59190614e11565b90815260200160405180910390205461415d565b60006128d583836126be565b80156128e857506128e6838361390b565b155b801561118357506128f98383614415565b159392505050565b60006111fa82600761457e565b60075460009081906001600160a01b0316331461292b573361292d565b325b9050600061293b828761118a565b9050600060108260405161294f9190614e11565b908152602001604051809103902054905060006013836040516129729190614e11565b908152602001604051809103902054600014156129ad576011836040516129999190614e11565b9081526020016040518091039020546129cd565b6013836040516129bd9190614e11565b9081526020016040518091039020545b90506129d984896126be565b612a145760405162461bcd60e51b815260206004820152600c60248201526b191bd95cdb9d08195e1a5cdd60a21b604482015260640161105f565b612a1e848961390b565b15612a5a5760405162461bcd60e51b815260206004820152600c60248201526b1b9bd91948195e1c1a5c995960a21b604482015260640161105f565b612a648489613897565b15612a9c5760405162461bcd60e51b8152602060048201526008602482015267706173742064756560c01b604482015260640161105f565b42871115612adc5760405162461bcd60e51b815260206004820152600d60248201526c06261642074696d657374616d7609c1b604482015260640161105f565b86612ae982610384614d1b565b10612b215760405162461bcd60e51b81526020600482015260086024820152673a37b79039b7b7b760c11b604482015260640161105f565b6000612b2e858a8a61245f565b905060008111612b6c5760405162461bcd60e51b81526020600482015260096024820152681b9bc81c995dd85c9960ba1b604482015260640161105f565b6006546040516370a0823160e01b815230600482015282916001600160a01b0316906370a082319060240160206040518083038186803b158015612baf57600080fd5b505afa158015612bc3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612be79190614dd2565b1015612c245760405162461bcd60e51b815260206004820152600c60248201526b6f7665722062616c616e636560a01b604482015260640161105f565b6000612c2f84614408565b612c3885613e1a565b612c429084614d89565b612c4c9190614dbe565b905080341015612c6e5760405162461bcd60e51b815260040161105f90614e56565b88601386604051612c7f9190614e11565b9081526040805160209281900383018120939093558c83529082018490526001600160a01b038816917f987d620f307ff6b94d58743cb7a7509f24071586a77759b77c2d4e29f75a2f9a910160405180910390a2336000908152600e602052604090205415612d6157336000908152600e6020526040902054821015612d3457336000908152600e6020526040902054612d1a908390614d72565b336000908152600e60205260408120919091559150612d61565b336000908152600e6020526040902054612d4e9083614d72565b336000908152600e602052604081205591505b8115612e7f576001600160a01b03881615612ddd576040516330d6a97560e01b81526001600160a01b038781166004830152602482018490528916906330d6a97590604401600060405180830381600087803b158015612dc057600080fd5b505af1158015612dd4573d6000803e3d6000fd5b50505050612e7f565b60065460405163a9059cbb60e01b81526001600160a01b038881166004830152602482018590529091169063a9059cbb90604401602060405180830381600087803b158015612e2b57600080fd5b505af1158015612e3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e639190614cc5565b612e7f5760405162461bcd60e51b815260040161105f90614e7b565b600b54612e95906001600160a01b031682614609565b612e9d614786565b8015612ea857508034115b15612ec057612ec033612ebb8334614d72565b614609565b9998505050505050505050565b6000612ed883611534565b90506000612ee58461357a565b90506000612ef285611200565b60008681526002602052604090205490915060ff16612f235760405162461bcd60e51b815260040161105f90614deb565b6009541580612f425750600954336000908152600d6020526040902054105b612f7b5760405162461bcd60e51b815260206004820152600a6024820152691bdd995c881b1a5b5a5d60b21b604482015260640161105f565b801580612fa15750336000908152600f6020908152604080832088845290915290205481115b612fda5760405162461bcd60e51b815260206004820152600a6024820152691bdd995c881b1a5b5a5d60b21b604482015260640161105f565b82341015612ffa5760405162461bcd60e51b815260040161105f90614e56565b336000908152600d6020526040812054613015906001614d1b565b90506000613023338361118a565b905060085460016130349190614d1b565b600855604051879060109061304a908490614e11565b9081526020016040518091039020819055504260118260405161306d9190614e11565b908152602001604051809103902081905550426012826040516130909190614e11565b908152604080516020928190038301902092909255336000908152600d90915220546130bd906001614d1b565b336000908152600d6020908152604080832093909355600f81528282208a8352905220546130ec906001614d1b565b336000818152600f602090815260408083208c84528252918290209390935580518a815292830185905288151590830152426060830152907f450a067d57712752555ba8fac2ec18dd15718b07539357bc1578ee837ef1422a9060800160405180910390a285156131b05783613162334261262c565b10156131805760405162461bcd60e51b815260040161105f90614d4e565b336000908152600e602052604090205461319b908590614d1b565b336000908152600e6020526040902055613349565b6000612710600a54866131c39190614d89565b6131cd9190614dbe565b9050801561327f57600654600b546040516323b872dd60e01b81523360048201526001600160a01b039182166024820152604481018490529116906323b872dd90606401602060405180830381600087803b15801561322b57600080fd5b505af115801561323f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132639190614cc5565b61327f5760405162461bcd60e51b815260040161105f90614e7b565b80851115613347576006546001600160a01b03166323b872dd33306132a4858a614d72565b6040516001600160e01b031960e086901b1681526001600160a01b0393841660048201529290911660248301526044820152606401602060405180830381600087803b1580156132f357600080fd5b505af1158015613307573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061332b9190614cc5565b6133475760405162461bcd60e51b815260040161105f90614e7b565b505b600b5461335f906001600160a01b031686614609565b843411156133755761337533612ebb8734614d72565b50505050505050565b600160009054906101000a90046001600160a01b03166001600160a01b0316637c7c7c3c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156133cc57600080fd5b505afa1580156133e0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134049190614c86565b6001546001600160a01b031615806134995750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f6906134499084903390600401614ca9565b60206040518083038186803b15801561346157600080fd5b505afa158015613475573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134999190614cc5565b6134b55760405162461bcd60e51b815260040161105f90614ce2565b600082116134c257600080fd5b6006546040516323b872dd60e01b8152336004820152306024820152604481018490526001600160a01b03909116906323b872dd90606401602060405180830381600087803b15801561351457600080fd5b505af1158015613528573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061354c9190614cc5565b6135685760405162461bcd60e51b815260040161105f90614e7b565b5050565b6000601261243b848461118a565b60006111fa82600261457e565b600160009054906101000a90046001600160a01b03166001600160a01b0316637c7c7c3c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156135d557600080fd5b505afa1580156135e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061360d9190614c86565b6001546001600160a01b031615806136a25750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f6906136529084903390600401614ca9565b60206040518083038186803b15801561366a57600080fd5b505afa15801561367e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136a29190614cc5565b6136be5760405162461bcd60e51b815260040161105f90614ce2565b50600680546001600160a01b0319166001600160a01b0392909216919091179055565b6000806136ee338461118a565b905060006010826040516137029190614e11565b9081526020016040518091039020549050600061371e8261415d565b905061372a33866128c9565b6137615760405162461bcd60e51b815260206004820152600860248201526763616e742070617960c01b604482015260640161105f565b803410156137815760405162461bcd60e51b815260040161105f90614e56565b61378a82612901565b60128460405161379a9190614e11565b9081526020016040518091039020546137b39190614d1b565b6012846040516137c39190614e11565b908152602001604051809103902081905550336001600160a01b03167f1ff60751a354563b8db02f735046d6cecdd1ec33b27b453a7925da806b529adb83876012876040516138129190614e11565b9081526040519081900360200181205461383e9392919283526020830191909152604082015260600190565b60405180910390a2600b5461385c906001600160a01b031682614609565b613864614786565b801561386f57508034115b156138825761388233612ebb8334614d72565b949350505050565b60006111fa82600861457e565b6000806138a4848461118a565b905060006010826040516138b89190614e11565b908152602001604051809103902054905060006012836040516138db9190614e11565b90815260200160405180910390205490506138f582612901565b6138ff9082614d1b565b42119695505050505050565b600080613918848461118a565b9050600060108260405161392c9190614e11565b9081526020016040518091039020549050600060128360405161394f9190614e11565b9081526020016040518091039020549050806000141561397557600193505050506111fa565b61397e8261388a565b61398783612901565b6139919083614d1b565b6138ff9190614d1b565b600160009054906101000a90046001600160a01b03166001600160a01b0316637c7c7c3c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156139e957600080fd5b505afa1580156139fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a219190614c86565b6001546001600160a01b03161580613ab65750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f690613a669084903390600401614ca9565b60206040518083038186803b158015613a7e57600080fd5b505afa158015613a92573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ab69190614cc5565b613ad25760405162461bcd60e51b815260040161105f90614ce2565b60065460405163095ea7b360e01b81526001600160a01b038581166004830152602482018590529091169063095ea7b390604401602060405180830381600087803b158015613b2057600080fd5b505af1158015613b34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b589190614cc5565b613b955760405162461bcd60e51b815260206004820152600e60248201526d185c1c1c9bdd994819985a5b195960921b604482015260640161105f565b505050565b6007546000906001600160a01b0316613bb557506000611183565b6000613bc1858561118a565b90506000601082604051613bd59190614e11565b90815260200160405180910390205490506000601383604051613bf89190614e11565b90815260200160405180910390205460001415613c3357601183604051613c1f9190614e11565b908152602001604051809103902054613c53565b601383604051613c439190614e11565b9081526020016040518091039020545b6007546040516394d14a9b60e01b81526001600160a01b038a811660048301526001600160801b038a166024830152306044830152929350600092909116906394d14a9b9060640160006040518083038186803b158015613cb357600080fd5b505afa158015613cc7573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613cef9190810190614ea4565b9050604051602001613d0c90602080825260009082015260400190565b6040516020818303038152906040528051906020012081604051602001613d3391906148e5565b604051602081830303815290604052805190602001201415613d5c576000945050505050611183565b6000613d6884836140c0565b905060008111613d79576000612ec0565b600754604051632034eb5160e01b81526001600160a01b038b811660048301526001600160801b038b16602483015260448201869052606482018a90526084820184905290911690632034eb519060a40160206040518083038186803b158015613de257600080fd5b505afa158015613df6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ec09190614dd2565b60006111fa82600561457e565b60026000908155338152600d6020526040902054613e725760405162461bcd60e51b81526020600482015260086024820152676e6f206e6f64657360c01b604482015260640161105f565b34600083613e81576001613e83565b835b90506000808411613ea357336000908152600d6020526040902054613ea5565b835b9050815b818111613f1057613eba33826128c9565b613ec357613efe565b60008411613ee35760405162461bcd60e51b815260040161105f90614d4e565b6000613eee826136e1565b9050613efa8186614d72565b9450505b80613f0881614d33565b915050613ea9565b508215613f2157613f213384614609565b50506001600055505050565b600160009054906101000a90046001600160a01b03166001600160a01b0316630fe175bb6040518163ffffffff1660e01b815260040160206040518083038186803b158015613f7b57600080fd5b505afa158015613f8f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fb39190614c86565b6001546001600160a01b031615806140485750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f690613ff89084903390600401614ca9565b60206040518083038186803b15801561401057600080fd5b505afa158015614024573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140489190614cc5565b6140645760405162461bcd60e51b815260040161105f90614ce2565b6001600160a01b0383166000818152600c6020908152604091829020805460ff19168615159081179091558251938452908301527fea782fa1fcb250a935b6bf028374e06a580a12523d2befc1c2254a3cd3ef378091016116c6565b60008281526005602052604080822090518291906140df908590614e11565b90815260200160405180910390205411614140576000805260056020526040517f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746bc9061412c908490614e11565b908152602001604051809103902054611183565b600083815260056020526040908190209051612448908490614e11565b60006111fa82600461457e565b600160009054906101000a90046001600160a01b03166001600160a01b0316637c7c7c3c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156141b857600080fd5b505afa1580156141cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141f09190614c86565b6001546001600160a01b031615806142855750600154604051634f4bdc7b60e11b81526001600160a01b0390911690639e97b8f6906142359084903390600401614ca9565b60206040518083038186803b15801561424d57600080fd5b505afa158015614261573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142859190614cc5565b6142a15760405162461bcd60e51b815260040161105f90614ce2565b600082116142ae57600080fd5b6006546040516370a0823160e01b815230600482015283916001600160a01b0316906370a082319060240160206040518083038186803b1580156142f157600080fd5b505afa158015614305573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143299190614dd2565b10156143665760405162461bcd60e51b815260206004820152600c60248201526b6f7665722062616c616e636560a01b604482015260640161105f565b60065460405163a9059cbb60e01b81526001600160a01b038581166004830152602482018590529091169063a9059cbb90604401602060405180830381600087803b1580156143b457600080fd5b505af11580156143c8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906143ec9190614cc5565b613b955760405162461bcd60e51b815260040161105f90614e7b565b60006111fa82600661457e565b600080614422848461118a565b905060006010826040516144369190614e11565b908152602001604051809103902054905060006012836040516144599190614e11565b9081526020016040518091039020549050600061447583612901565b90506000614482846126f2565b61448c9083614d89565b6144969042614d1b565b9050806144a38385614d1b565b101598975050505050505050565b60008080846144c15760016144c3565b845b905060008085116144ec576001600160a01b0388166000908152600d60205260409020546144ee565b845b9050815b8181116145715760006145148a8360008c1161450e574261245f565b8b61245f565b9050801561455e5760006145288b8461242d565b905061453381614408565b61453c82613e1a565b6145469084614d89565b6145509190614dbe565b61455a9087614d1b565b9550505b508061456981614d33565b9150506144f2565b5091979650505050505050565b60008281526003602052604081205460ff1680156145b45750600083815260046020908152604080832085845290915290205415155b6145eb5760008281527f17ef568e3e12ab5b9c7254a8d58478811de00f9e6eb34345acd53bf8fd09d3ec6020526040902054611183565b50600091825260046020908152604080842092845291905290205490565b804710156146505760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b604482015260640161105f565b6000826001600160a01b03168260405160006040518083038185875af1925050503d806000811461469d576040519150601f19603f3d011682016040523d82523d6000602084013e6146a2565b606091505b5050905080613b955760405162461bcd60e51b815260206004820152600b60248201526a1cd95b990819985a5b195960aa1b604482015260640161105f565b6000631f5405008211156146f757631f54050091505b8161470b5750670de0b6b3a76400006111fa565b670de0b6b3a764000083835b600181111561477c5761472b600282614f1b565b61474d57614739828361479c565b9150614746600282614dbe565b9050614717565b614757828461479c565b9250614763828361479c565b91506002614772600183614d72565b6147469190614dbe565b61152a828461479c565b60008054600214158015611c6457505033321490565b6000806147a98385614d89565b9050670de0b6b3a76400006147bf600282614dbe565b6147c99083614d1b565b6138829190614dbe565b6001600160a01b03811681146147e857600080fd5b50565b600080604083850312156147fe57600080fd5b8235614809816147d3565b946020939093013593505050565b60008060006060848603121561482c57600080fd5b8335614837816147d3565b92506020840135614847816147d3565b929592945050506040919091013590565b60008060006060848603121561486d57600080fd5b8335614878816147d3565b95602085013595506040909401359392505050565b60005b838110156148a8578181015183820152602001614890565b838111156110f35750506000910152565b600081518084526148d181602086016020860161488d565b601f01601f19169290920160200192915050565b60208152600061118360208301846148b9565b60006020828403121561490a57600080fd5b5035919050565b60008060006060848603121561492657600080fd5b8335614931816147d3565b92506020840135614941816147d3565b91506040840135614951816147d3565b809150509250925092565b6000806000806080858703121561497257600080fd5b843593506020850135614984816147d3565b93969395505050506040820135916060013590565b6000602082840312156149ab57600080fd5b8135611183816147d3565b6000806000606084860312156149cb57600080fd5b505081359360208301359350604090920135919050565b80151581146147e857600080fd5b60008060408385031215614a0357600080fd5b823591506020830135614a15816149e2565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff81118282101715614a5f57614a5f614a20565b604052919050565b600067ffffffffffffffff821115614a8157614a81614a20565b50601f01601f191660200190565b6000614aa2614a9d84614a67565b614a36565b9050828152838383011115614ab657600080fd5b828260208301376000602084830101529392505050565b600082601f830112614ade57600080fd5b61118383833560208501614a8f565b60008060408385031215614b0057600080fd5b82359150602083013567ffffffffffffffff811115614b1e57600080fd5b614b2a85828601614acd565b9150509250929050565b600080600060608486031215614b4957600080fd5b83359250602084013567ffffffffffffffff811115614b6757600080fd5b614b7386828701614acd565b925050604084013590509250925092565b600060208284031215614b9657600080fd5b813567ffffffffffffffff811115614bad57600080fd5b8201601f81018413614bbe57600080fd5b61388284823560208401614a8f565b600080600060608486031215614be257600080fd5b83359250602084013591506040840135614951816147d3565b60008060408385031215614c0e57600080fd5b50508035926020909101359150565b60008060408385031215614c3057600080fd5b8235614c3b816147d3565b91506020830135614a15816149e2565b60008060008060808587031215614c6157600080fd5b8435614c6c816147d3565b966020860135965060408601359560600135945092505050565b600060208284031215614c9857600080fd5b815160ff8116811461118357600080fd5b60ff9290921682526001600160a01b0316602082015260400190565b600060208284031215614cd757600080fd5b8151611183816149e2565b6020808252600990820152686e6f2061636365737360b81b604082015260600190565b634e487b7160e01b600052601160045260246000fd5b60008219821115614d2e57614d2e614d05565b500190565b6000600019821415614d4757614d47614d05565b5060010190565b6020808252600a90820152690dcdee840cadcdeeaced60b31b604082015260600190565b600082821015614d8457614d84614d05565b500390565b6000816000190483118215151615614da357614da3614d05565b500290565b634e487b7160e01b600052601260045260246000fd5b600082614dcd57614dcd614da8565b500490565b600060208284031215614de457600080fd5b5051919050565b6020808252600c908201526b696e76616c6964207479706560a01b604082015260600190565b60008251614e2381846020870161488d565b9190910192915050565b838152606060208201526000614e4660608301856148b9565b9050826040830152949350505050565b6020808252600b908201526a696e76616c69642066656560a81b604082015260600190565b6020808252600f908201526e1d1c985b9cd9995c8819985a5b1959608a1b604082015260600190565b600060208284031215614eb657600080fd5b815167ffffffffffffffff811115614ecd57600080fd5b8201601f81018413614ede57600080fd5b8051614eec614a9d82614a67565b818152856020838501011115614f0157600080fd5b614f1282602083016020860161488d565b95945050505050565b600082614f2a57614f2a614da8565b50069056fea264697066735822122000b507d9b6d3ec2a4d5bfd94f37852e762e6137e0804b8bbd2449b11ac1a67ba64736f6c63430008090033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.