ETH Price: $2,406.26 (+7.41%)

Transaction Decoder

Block:
10615091 at Aug-07-2020 09:17:24 PM +UTC
Transaction Fee:
0.02827823808 ETH $68.04
Gas Used:
527,776 Gas / 53.58 Gwei

Emitted Events:

75 Nest_3_OfferMain.OfferContractAddress( contractAddress=0x00000000...000008e77, tokenAddress=[Receiver] TetherToken, ethAmount=10000000000000000000, erc20Amount=3787200000, continued=25, serviceCharge=100000000000000000 )
76 TetherToken.Transfer( from=[Sender] 0x3d29e80185c78555ec9052b393135e6a2db56fd1, to=[Receiver] Nest_3_OfferMain, value=3787200000 )
77 IBNEST.Transfer( from=Nest_3_MiningContract, to=[Receiver] Nest_3_OfferMain, value=2240000000000000000000 )
78 Nest_3_MiningContract.OreDrawingLog( nowBlock=10615091, blockAmount=2240000000000000000000 )
79 IBNEST.Transfer( from=[Receiver] Nest_3_OfferMain, to=NEST_NodeSave, value=336000000000000000000 )
80 IBNEST.Transfer( from=[Receiver] Nest_3_OfferMain, to=0x6756927922D2A32cB799F261e4aBC47652CDE54b, value=112000000000000000000 )

Account State Difference:

  Address   Before After State Difference Code
0x04abEdA2...c74ddC74C
0x2f979C93...780555b0a
(NEST Protocol: Mining Pool)
0x3D29e801...A2Db56Fd1
81.540420488041113098 Eth
Nonce: 29646
71.412142249961113098 Eth
Nonce: 29647
10.12827823808
0x43121397...e39D44852
(NEST Protocol: Revenue Pool)
557.158226885336486457 Eth557.258226885336486457 Eth0.1
(Spark Pool)
80.65351940188668127 Eth80.68179763996668127 Eth0.02827823808
0x7722891E...23cFd270F
(NEST Protocol: Oracle Call)
0xb086F99E...17BBc6cbC
0xc83E009c...Fc4D039F6
(NEST Protocol: Oracle ETH/USDT)
430 Eth440 Eth10
0xdAC17F95...13D831ec7

Execution Trace

ETH 10.1 Nest_3_OfferMain.offer( ethAmount=10000000000000000000, erc20Amount=3787200000, erc20Address=0xdAC17F958D2ee523a2206206994597C13D831ec7 )
  • Nest_3_OfferPrice.updateAndCheckPricePrivate( tokenAddress=0xdAC17F958D2ee523a2206206994597C13D831ec7 ) => ( ethAmount=10000000000000000000, erc20Amount=3788500000 )
  • Nest_3_OfferPrice.addPrice( ethAmount=10000000000000000000, tokenAmount=3787200000, endBlock=10615116, tokenAddress=0xdAC17F958D2ee523a2206206994597C13D831ec7, offerOwner=0x3D29e80185C78555eC9052b393135e6A2Db56Fd1 )
  • TetherToken.transferFrom( _from=0x3D29e80185C78555eC9052b393135e6A2Db56Fd1, _to=0xc83E009c7794e8f6d1954dc13c23A35Fc4D039F6, _value=3787200000 )
  • Nest_3_MiningContract.CALL( )
    • IBNEST.balanceOf( _owner=0x2f979C933AEF4fCDdD27C0Fa5C54d8a780555b0a ) => ( 8373905964188881024933952036 )
      • IterableMapping.4c5e1cae( )
      • IBNEST.transfer( _to=0xc83E009c7794e8f6d1954dc13c23A35Fc4D039F6, _value=2240000000000000000000 ) => ( True )
        • IterableMapping.4c5e1cae( )
        • IterableMapping.4c5e1cae( )
        • IterableMapping.ab517b4f( )
        • IterableMapping.4c5e1cae( )
        • IterableMapping.ab517b4f( )
        • ETH 0.1 Nest_3_Abonus.switchToEth( token=0x04abEdA201850aC0124161F037Efd70c74ddC74C )
        • NEST_NodeAssignment.bookKeeping( amount=336000000000000000000 )
          • IBNEST.transferFrom( _from=0xc83E009c7794e8f6d1954dc13c23A35Fc4D039F6, _to=0x101D8b63A081dFfF2B1364864345b7F071b052ac, _value=336000000000000000000 ) => ( True )
            • IterableMapping.4c5e1cae( )
            • IterableMapping.4c5e1cae( )
            • IterableMapping.ab517b4f( )
            • IterableMapping.4c5e1cae( )
            • IterableMapping.ab517b4f( )
            • NEST_NodeAssignmentData.addNest( amount=336000000000000000000 )
              • Nest_3_VoteFactory.checkAddress( name=nodeAssignment ) => ( contractAddress=0x39D0f58f5D5BBD636be23a3184Aff16a4D7567CF )
              • IBNEST.transfer( _to=0x6756927922D2A32cB799F261e4aBC47652CDE54b, _value=112000000000000000000 ) => ( True )
                • IterableMapping.4c5e1cae( )
                • IterableMapping.4c5e1cae( )
                • IterableMapping.ab517b4f( )
                • IterableMapping.4c5e1cae( )
                • IterableMapping.ab517b4f( )
                  File 1 of 11: Nest_3_OfferMain
                  pragma solidity 0.6.0;
                  
                  /**
                   * @title Offering contract
                   * @dev Offering + take order + NEST allocation
                   */
                  contract Nest_3_OfferMain {
                      using SafeMath for uint256;
                      using address_make_payable for address;
                      using SafeERC20 for ERC20;
                      
                      struct Nest_3_OfferPriceData {
                          // The unique identifier is determined by the position of the offer in the array, and is converted to each other through a fixed algorithm (toindex(), toaddress())
                          
                          address owner;                                  //  Offering owner
                          bool deviate;                                   //  Whether it deviates 
                          address tokenAddress;                           //  The erc20 contract address of the target offer token
                          
                          uint256 ethAmount;                              //  The ETH amount in the offer list
                          uint256 tokenAmount;                            //  The token amount in the offer list
                          
                          uint256 dealEthAmount;                          //  The remaining number of tradable ETH
                          uint256 dealTokenAmount;                        //  The remaining number of tradable tokens
                          
                          uint256 blockNum;                               //  The block number where the offer is located
                          uint256 serviceCharge;                          //  The fee for mining
                          
                          // Determine whether the asset has been collected by judging that ethamount, tokenamount, and servicecharge are all 0
                      }
                      
                      Nest_3_OfferPriceData [] _prices;                   //  Array used to save offers
                  
                      mapping(address => bool) _tokenAllow;               //  List of allowed mining token
                      Nest_3_VoteFactory _voteFactory;                    //  Vote contract
                      Nest_3_OfferPrice _offerPrice;                      //  Price contract
                      Nest_3_MiningContract _miningContract;              //  Mining contract
                      Nest_NodeAssignment _NNcontract;                    //  NestNode contract
                      ERC20 _nestToken;                                   //  NestToken
                      Nest_3_Abonus _abonus;                              //  Bonus pool
                      address _coderAddress;                              //  Developer address
                      uint256 _miningETH = 10;                            //  Offering mining fee ratio
                      uint256 _tranEth = 1;                               //  Taker fee ratio
                      uint256 _tranAddition = 2;                          //  Additional transaction multiple
                      uint256 _coderAmount = 5;                           //  Developer ratio
                      uint256 _NNAmount = 15;                             //  NestNode ratio
                      uint256 _leastEth = 10 ether;                       //  Minimum offer of ETH
                      uint256 _offerSpan = 10 ether;                      //  ETH Offering span
                      uint256 _deviate = 10;                              //  Price deviation - 10%
                      uint256 _deviationFromScale = 10;                   //  Deviation from asset scale
                      uint32 _blockLimit = 25;                            //  Block interval upper limit
                      mapping(uint256 => uint256) _offerBlockEth;         //  Block offer fee
                      mapping(uint256 => uint256) _offerBlockMining;      //  Block mining amount
                      
                      //  Log offering contract, token address, number of eth, number of erc20, number of continuous blocks, number of fees
                      event OfferContractAddress(address contractAddress, address tokenAddress, uint256 ethAmount, uint256 erc20Amount, uint256 continued, uint256 serviceCharge);
                      //  Log transaction, transaction initiator, transaction token address, number of transaction token, token address, number of token, traded offering contract address, traded user address
                      event OfferTran(address tranSender, address tranToken, uint256 tranAmount,address otherToken, uint256 otherAmount, address tradedContract, address tradedOwner);        
                      
                       /**
                      * @dev Initialization method
                      * @param voteFactory Voting contract address
                      */
                      constructor (address voteFactory) public {
                          Nest_3_VoteFactory voteFactoryMap = Nest_3_VoteFactory(address(voteFactory));
                          _voteFactory = voteFactoryMap; 
                          _offerPrice = Nest_3_OfferPrice(address(voteFactoryMap.checkAddress("nest.v3.offerPrice")));            
                          _miningContract = Nest_3_MiningContract(address(voteFactoryMap.checkAddress("nest.v3.miningSave")));
                          _abonus = Nest_3_Abonus(voteFactoryMap.checkAddress("nest.v3.abonus"));
                          _nestToken = ERC20(voteFactoryMap.checkAddress("nest"));                                         
                          _NNcontract = Nest_NodeAssignment(address(voteFactoryMap.checkAddress("nodeAssignment")));      
                          _coderAddress = voteFactoryMap.checkAddress("nest.v3.coder");
                          require(_nestToken.approve(address(_NNcontract), uint256(10000000000 ether)), "Authorization failed");
                      }
                      
                       /**
                      * @dev Reset voting contract
                      * @param voteFactory Voting contract address
                      */
                      function changeMapping(address voteFactory) public onlyOwner {
                          Nest_3_VoteFactory voteFactoryMap = Nest_3_VoteFactory(address(voteFactory));
                          _voteFactory = voteFactoryMap; 
                          _offerPrice = Nest_3_OfferPrice(address(voteFactoryMap.checkAddress("nest.v3.offerPrice")));            
                          _miningContract = Nest_3_MiningContract(address(voteFactoryMap.checkAddress("nest.v3.miningSave")));
                          _abonus = Nest_3_Abonus(voteFactoryMap.checkAddress("nest.v3.abonus"));
                          _nestToken = ERC20(voteFactoryMap.checkAddress("nest"));                                           
                          _NNcontract = Nest_NodeAssignment(address(voteFactoryMap.checkAddress("nodeAssignment")));      
                          _coderAddress = voteFactoryMap.checkAddress("nest.v3.coder");
                          require(_nestToken.approve(address(_NNcontract), uint256(10000000000 ether)), "Authorization failed");
                      }
                      
                      /**
                      * @dev Offering mining
                      * @param ethAmount Offering ETH amount 
                      * @param erc20Amount Offering erc20 token amount
                      * @param erc20Address Offering erc20 token address
                      */
                      function offer(uint256 ethAmount, uint256 erc20Amount, address erc20Address) public payable {
                          require(address(msg.sender) == address(tx.origin), "It can't be a contract");
                          require(_tokenAllow[erc20Address], "Token not allow");
                          //  Judge whether the price deviates
                          uint256 ethMining;
                          bool isDeviate = comparativePrice(ethAmount,erc20Amount,erc20Address);
                          if (isDeviate) {
                              require(ethAmount >= _leastEth.mul(_deviationFromScale), "EthAmount needs to be no less than 10 times of the minimum scale");
                              ethMining = _leastEth.mul(_miningETH).div(1000);
                          } else {
                              ethMining = ethAmount.mul(_miningETH).div(1000);
                          }
                          require(msg.value >= ethAmount.add(ethMining), "msg.value needs to be equal to the quoted eth quantity plus Mining handling fee");
                          uint256 subValue = msg.value.sub(ethAmount.add(ethMining));
                          if (subValue > 0) {
                              repayEth(address(msg.sender), subValue);
                          }
                          //  Create an offer
                          createOffer(ethAmount, erc20Amount, erc20Address, ethMining, isDeviate);
                          //  Transfer in offer asset - erc20 to this contract
                          ERC20(erc20Address).safeTransferFrom(address(msg.sender), address(this), erc20Amount);
                          //  Mining
                          uint256 miningAmount = _miningContract.oreDrawing();
                          _abonus.switchToEth.value(ethMining)(address(_nestToken));
                          if (miningAmount > 0) {
                              uint256 coder = miningAmount.mul(_coderAmount).div(100);
                              uint256 NN = miningAmount.mul(_NNAmount).div(100);
                              uint256 other = miningAmount.sub(coder).sub(NN);
                              _offerBlockMining[block.number] = other;
                              _NNcontract.bookKeeping(NN);   
                              if (coder > 0) {
                                  _nestToken.safeTransfer(_coderAddress, coder);  
                              }
                          }
                          _offerBlockEth[block.number] = _offerBlockEth[block.number].add(ethMining);
                      }
                      
                      /**
                      * @dev Create offer
                      * @param ethAmount Offering ETH amount
                      * @param erc20Amount Offering erc20 amount
                      * @param erc20Address Offering erc20 address
                      * @param mining Offering mining fee (0 for takers)
                      * @param isDeviate Whether the current price chain deviates
                      */
                      function createOffer(uint256 ethAmount, uint256 erc20Amount, address erc20Address, uint256 mining, bool isDeviate) private {
                          // Check offer conditions
                          require(ethAmount >= _leastEth, "Eth scale is smaller than the minimum scale");
                          require(ethAmount % _offerSpan == 0, "Non compliant asset span");
                          require(erc20Amount % (ethAmount.div(_offerSpan)) == 0, "Asset quantity is not divided");
                          require(erc20Amount > 0);
                          // Create offering contract
                          emit OfferContractAddress(toAddress(_prices.length), address(erc20Address), ethAmount, erc20Amount,_blockLimit,mining);
                          _prices.push(Nest_3_OfferPriceData(
                              
                              msg.sender,
                              isDeviate,
                              erc20Address,
                              
                              ethAmount,
                              erc20Amount,
                                             
                              ethAmount, 
                              erc20Amount, 
                                
                              block.number, 
                              mining
                              
                          )); 
                          // Record price
                          _offerPrice.addPrice(ethAmount, erc20Amount, block.number.add(_blockLimit), erc20Address, address(msg.sender));
                      }
                      
                      /**
                      * @dev Taker order - pay ETH and buy erc20
                      * @param ethAmount The amount of ETH of this offer
                      * @param tokenAmount The amount of erc20 of this offer
                      * @param contractAddress The target offer address
                      * @param tranEthAmount The amount of ETH of taker order
                      * @param tranTokenAmount The amount of erc20 of taker order
                      * @param tranTokenAddress The erc20 address of taker order
                      */
                      function sendEthBuyErc(uint256 ethAmount, uint256 tokenAmount, address contractAddress, uint256 tranEthAmount, uint256 tranTokenAmount, address tranTokenAddress) public payable {
                          require(address(msg.sender) == address(tx.origin), "It can't be a contract");
                          // Get the offer data structure
                          uint256 index = toIndex(contractAddress);
                          Nest_3_OfferPriceData memory offerPriceData = _prices[index]; 
                          //  Check the price, compare the current offer to the last effective price
                          bool thisDeviate = comparativePrice(ethAmount,tokenAmount,tranTokenAddress);
                          bool isDeviate;
                          if (offerPriceData.deviate == true) {
                              isDeviate = true;
                          } else {
                              isDeviate = thisDeviate;
                          }
                          // Limit the taker order only be twice the amount of the offer to prevent large-amount attacks
                          if (offerPriceData.deviate) {
                              //  The taker order deviates  x2
                              require(ethAmount >= tranEthAmount.mul(_tranAddition), "EthAmount needs to be no less than 2 times of transaction scale");
                          } else {
                              if (isDeviate) {
                                  //  If the taken offer is normal and the taker order deviates x10
                                  require(ethAmount >= tranEthAmount.mul(_deviationFromScale), "EthAmount needs to be no less than 10 times of transaction scale");
                              } else {
                                  //  If the taken offer is normal and the taker order is normal x2
                                  require(ethAmount >= tranEthAmount.mul(_tranAddition), "EthAmount needs to be no less than 2 times of transaction scale");
                              }
                          }
                          
                          uint256 serviceCharge = tranEthAmount.mul(_tranEth).div(1000);
                          require(msg.value == ethAmount.add(tranEthAmount).add(serviceCharge), "msg.value needs to be equal to the quotation eth quantity plus transaction eth plus transaction handling fee");
                          require(tranEthAmount % _offerSpan == 0, "Transaction size does not meet asset span");
                          
                          // Check whether the conditions for taker order are satisfied
                          require(checkContractState(offerPriceData.blockNum) == 0, "Offer status error");
                          require(offerPriceData.dealEthAmount >= tranEthAmount, "Insufficient trading eth");
                          require(offerPriceData.dealTokenAmount >= tranTokenAmount, "Insufficient trading token");
                          require(offerPriceData.tokenAddress == tranTokenAddress, "Wrong token address");
                          require(tranTokenAmount == offerPriceData.dealTokenAmount * tranEthAmount / offerPriceData.dealEthAmount, "Wrong token amount");
                          
                          // Update the offer information
                          offerPriceData.ethAmount = offerPriceData.ethAmount.add(tranEthAmount);
                          offerPriceData.tokenAmount = offerPriceData.tokenAmount.sub(tranTokenAmount);
                          offerPriceData.dealEthAmount = offerPriceData.dealEthAmount.sub(tranEthAmount);
                          offerPriceData.dealTokenAmount = offerPriceData.dealTokenAmount.sub(tranTokenAmount);
                          _prices[index] = offerPriceData;
                          // Create a new offer
                          createOffer(ethAmount, tokenAmount, tranTokenAddress, 0, isDeviate);
                          // Transfer in erc20 + offer asset to this contract
                          if (tokenAmount > tranTokenAmount) {
                              ERC20(tranTokenAddress).safeTransferFrom(address(msg.sender), address(this), tokenAmount.sub(tranTokenAmount));
                          } else {
                              ERC20(tranTokenAddress).safeTransfer(address(msg.sender), tranTokenAmount.sub(tokenAmount));
                          }
                          // Modify price
                          _offerPrice.changePrice(tranEthAmount, tranTokenAmount, tranTokenAddress, offerPriceData.blockNum.add(_blockLimit));
                          emit OfferTran(address(msg.sender), address(0x0), tranEthAmount, address(tranTokenAddress), tranTokenAmount, contractAddress, offerPriceData.owner);
                          // Transfer fee
                          if (serviceCharge > 0) {
                              _abonus.switchToEth.value(serviceCharge)(address(_nestToken));
                          }
                      }
                      
                      /**
                      * @dev Taker order - pay erc20 and buy ETH
                      * @param ethAmount The amount of ETH of this offer
                      * @param tokenAmount The amount of erc20 of this offer
                      * @param contractAddress The target offer address
                      * @param tranEthAmount The amount of ETH of taker order
                      * @param tranTokenAmount The amount of erc20 of taker order
                      * @param tranTokenAddress The erc20 address of taker order
                      */
                      function sendErcBuyEth(uint256 ethAmount, uint256 tokenAmount, address contractAddress, uint256 tranEthAmount, uint256 tranTokenAmount, address tranTokenAddress) public payable {
                          require(address(msg.sender) == address(tx.origin), "It can't be a contract");
                          // Get the offer data structure
                          uint256 index = toIndex(contractAddress);
                          Nest_3_OfferPriceData memory offerPriceData = _prices[index]; 
                          // Check the price, compare the current offer to the last effective price
                          bool thisDeviate = comparativePrice(ethAmount,tokenAmount,tranTokenAddress);
                          bool isDeviate;
                          if (offerPriceData.deviate == true) {
                              isDeviate = true;
                          } else {
                              isDeviate = thisDeviate;
                          }
                          // Limit the taker order only be twice the amount of the offer to prevent large-amount attacks
                          if (offerPriceData.deviate) {
                              //  The taker order deviates  x2
                              require(ethAmount >= tranEthAmount.mul(_tranAddition), "EthAmount needs to be no less than 2 times of transaction scale");
                          } else {
                              if (isDeviate) {
                                  //  If the taken offer is normal and the taker order deviates x10
                                  require(ethAmount >= tranEthAmount.mul(_deviationFromScale), "EthAmount needs to be no less than 10 times of transaction scale");
                              } else {
                                  //  If the taken offer is normal and the taker order is normal x2 
                                  require(ethAmount >= tranEthAmount.mul(_tranAddition), "EthAmount needs to be no less than 2 times of transaction scale");
                              }
                          }
                          uint256 serviceCharge = tranEthAmount.mul(_tranEth).div(1000);
                          require(msg.value == ethAmount.sub(tranEthAmount).add(serviceCharge), "msg.value needs to be equal to the quoted eth quantity plus transaction handling fee");
                          require(tranEthAmount % _offerSpan == 0, "Transaction size does not meet asset span");
                          
                          // Check whether the conditions for taker order are satisfied
                          require(checkContractState(offerPriceData.blockNum) == 0, "Offer status error");
                          require(offerPriceData.dealEthAmount >= tranEthAmount, "Insufficient trading eth");
                          require(offerPriceData.dealTokenAmount >= tranTokenAmount, "Insufficient trading token");
                          require(offerPriceData.tokenAddress == tranTokenAddress, "Wrong token address");
                          require(tranTokenAmount == offerPriceData.dealTokenAmount * tranEthAmount / offerPriceData.dealEthAmount, "Wrong token amount");
                          
                          // Update the offer information
                          offerPriceData.ethAmount = offerPriceData.ethAmount.sub(tranEthAmount);
                          offerPriceData.tokenAmount = offerPriceData.tokenAmount.add(tranTokenAmount);
                          offerPriceData.dealEthAmount = offerPriceData.dealEthAmount.sub(tranEthAmount);
                          offerPriceData.dealTokenAmount = offerPriceData.dealTokenAmount.sub(tranTokenAmount);
                          _prices[index] = offerPriceData;
                          // Create a new offer
                          createOffer(ethAmount, tokenAmount, tranTokenAddress, 0, isDeviate);
                          // Transfer in erc20 + offer asset to this contract
                          ERC20(tranTokenAddress).safeTransferFrom(address(msg.sender), address(this), tranTokenAmount.add(tokenAmount));
                          // Modify price
                          _offerPrice.changePrice(tranEthAmount, tranTokenAmount, tranTokenAddress, offerPriceData.blockNum.add(_blockLimit));
                          emit OfferTran(address(msg.sender), address(tranTokenAddress), tranTokenAmount, address(0x0), tranEthAmount, contractAddress, offerPriceData.owner);
                          // Transfer fee
                          if (serviceCharge > 0) {
                              _abonus.switchToEth.value(serviceCharge)(address(_nestToken));
                          }
                      }
                      
                      /**
                      * @dev Withdraw the assets, and settle the mining
                      * @param contractAddress The offer address to withdraw
                      */
                      function turnOut(address contractAddress) public {
                          require(address(msg.sender) == address(tx.origin), "It can't be a contract");
                          uint256 index = toIndex(contractAddress);
                          Nest_3_OfferPriceData storage offerPriceData = _prices[index]; 
                          require(checkContractState(offerPriceData.blockNum) == 1, "Offer status error");
                          
                          // Withdraw ETH
                          if (offerPriceData.ethAmount > 0) {
                              uint256 payEth = offerPriceData.ethAmount;
                              offerPriceData.ethAmount = 0;
                              repayEth(offerPriceData.owner, payEth);
                          }
                          
                          // Withdraw erc20
                          if (offerPriceData.tokenAmount > 0) {
                              uint256 payErc = offerPriceData.tokenAmount;
                              offerPriceData.tokenAmount = 0;
                              ERC20(address(offerPriceData.tokenAddress)).safeTransfer(offerPriceData.owner, payErc);
                              
                          }
                          // Mining settlement
                          if (offerPriceData.serviceCharge > 0) {
                              uint256 myMiningAmount = offerPriceData.serviceCharge.mul(_offerBlockMining[offerPriceData.blockNum]).div(_offerBlockEth[offerPriceData.blockNum]);
                              _nestToken.safeTransfer(offerPriceData.owner, myMiningAmount);
                              offerPriceData.serviceCharge = 0;
                          }
                          
                      }
                      
                      // Convert offer address into index in offer array
                      function toIndex(address contractAddress) public pure returns(uint256) {
                          return uint256(contractAddress);
                      }
                      
                      // Convert index in offer array into offer address 
                      function toAddress(uint256 index) public pure returns(address) {
                          return address(index);
                      }
                      
                      // View contract state
                      function checkContractState(uint256 createBlock) public view returns (uint256) {
                          if (block.number.sub(createBlock) > _blockLimit) {
                              return 1;
                          }
                          return 0;
                      }
                  
                      // Compare the order price
                      function comparativePrice(uint256 myEthValue, uint256 myTokenValue, address token) private view returns(bool) {
                          (uint256 frontEthValue, uint256 frontTokenValue) = _offerPrice.updateAndCheckPricePrivate(token);
                          if (frontEthValue == 0 || frontTokenValue == 0) {
                              return false;
                          }
                          uint256 maxTokenAmount = myEthValue.mul(frontTokenValue).mul(uint256(100).add(_deviate)).div(frontEthValue.mul(100));
                          if (myTokenValue <= maxTokenAmount) {
                              uint256 minTokenAmount = myEthValue.mul(frontTokenValue).mul(uint256(100).sub(_deviate)).div(frontEthValue.mul(100));
                              if (myTokenValue >= minTokenAmount) {
                                  return false;
                              }
                          }
                          return true;
                      }
                      
                      // Transfer ETH
                      function repayEth(address accountAddress, uint256 asset) private {
                          address payable addr = accountAddress.make_payable();
                          addr.transfer(asset);
                      }
                      
                      // View the upper limit of the block interval
                      function checkBlockLimit() public view returns(uint32) {
                          return _blockLimit;
                      }
                      
                      // View offering mining fee ratio
                      function checkMiningETH() public view returns (uint256) {
                          return _miningETH;
                      }
                      
                      // View whether the token is allowed to mine
                      function checkTokenAllow(address token) public view returns(bool) {
                          return _tokenAllow[token];
                      }
                      
                      // View additional transaction multiple
                      function checkTranAddition() public view returns(uint256) {
                          return _tranAddition;
                      }
                      
                      // View the development allocation ratio
                      function checkCoderAmount() public view returns(uint256) {
                          return _coderAmount;
                      }
                      
                      // View the NestNode allocation ratio
                      function checkNNAmount() public view returns(uint256) {
                          return _NNAmount;
                      }
                      
                      // View the least offering ETH 
                      function checkleastEth() public view returns(uint256) {
                          return _leastEth;
                      }
                      
                      // View offering ETH span
                      function checkOfferSpan() public view returns(uint256) {
                          return _offerSpan;
                      }
                      
                      // View the price deviation
                      function checkDeviate() public view returns(uint256){
                          return _deviate;
                      }
                      
                      // View deviation from scale
                      function checkDeviationFromScale() public view returns(uint256) {
                          return _deviationFromScale;
                      }
                      
                      // View block offer fee
                      function checkOfferBlockEth(uint256 blockNum) public view returns(uint256) {
                          return _offerBlockEth[blockNum];
                      }
                      
                      // View taker order fee ratio
                      function checkTranEth() public view returns (uint256) {
                          return _tranEth;
                      }
                      
                      // View block mining amount of user
                      function checkOfferBlockMining(uint256 blockNum) public view returns(uint256) {
                          return _offerBlockMining[blockNum];
                      }
                  
                      // View offer mining amount
                      function checkOfferMining(uint256 blockNum, uint256 serviceCharge) public view returns (uint256) {
                          if (serviceCharge == 0) {
                              return 0;
                          } else {
                              return _offerBlockMining[blockNum].mul(serviceCharge).div(_offerBlockEth[blockNum]);
                          }
                      }
                      
                      // Change offering mining fee ratio
                      function changeMiningETH(uint256 num) public onlyOwner {
                          _miningETH = num;
                      }
                      
                      // Modify taker fee ratio
                      function changeTranEth(uint256 num) public onlyOwner {
                          _tranEth = num;
                      }
                      
                      // Modify the upper limit of the block interval
                      function changeBlockLimit(uint32 num) public onlyOwner {
                          _blockLimit = num;
                      }
                      
                      // Modify whether the token allows mining
                      function changeTokenAllow(address token, bool allow) public onlyOwner {
                          _tokenAllow[token] = allow;
                      }
                      
                      // Modify additional transaction multiple
                      function changeTranAddition(uint256 num) public onlyOwner {
                          require(num > 0, "Parameter needs to be greater than 0");
                          _tranAddition = num;
                      }
                      
                      // Modify the initial allocation ratio
                      function changeInitialRatio(uint256 coderNum, uint256 NNNum) public onlyOwner {
                          require(coderNum.add(NNNum) <= 100, "User allocation ratio error");
                          _coderAmount = coderNum;
                          _NNAmount = NNNum;
                      }
                      
                      // Modify the minimum offering ETH
                      function changeLeastEth(uint256 num) public onlyOwner {
                          require(num > 0);
                          _leastEth = num;
                      }
                      
                      //  Modify the offering ETH span
                      function changeOfferSpan(uint256 num) public onlyOwner {
                          require(num > 0);
                          _offerSpan = num;
                      }
                      
                      // Modify the price deviation
                      function changekDeviate(uint256 num) public onlyOwner {
                          _deviate = num;
                      }
                      
                      // Modify the deviation from scale 
                      function changeDeviationFromScale(uint256 num) public onlyOwner {
                          _deviationFromScale = num;
                      }
                      
                      /**
                       * Get the number of offers stored in the offer array
                       * @return The number of offers stored in the offer array
                       **/
                      function getPriceCount() view public returns (uint256) {
                          return _prices.length;
                      }
                      
                      /**
                       * Get offer information according to the index
                       * @param priceIndex Offer index
                       * @return Offer information
                       **/
                      function getPrice(uint256 priceIndex) view public returns (string memory) {
                          // The buffer array used to generate the result string
                          bytes memory buf = new bytes(500000);
                          uint256 index = 0;
                          
                          index = writeOfferPriceData(priceIndex, _prices[priceIndex], buf, index);
                          
                          //  Generate the result string and return
                          bytes memory str = new bytes(index);
                          while(index-- > 0) {
                              str[index] = buf[index];
                          }
                          return string(str);
                      }
                      
                      /**
                       * Search the contract address list of the target account (reverse order)
                       * @param start Search forward from the index corresponding to the given contract address (not including the record corresponding to start address)
                       * @param count Maximum number of records to return
                       * @param maxFindCount The max index to search
                       * @param owner Target account address
                       * @return Separate the offer records with symbols. use , to divide fields: 
                       * uuid,owner,tokenAddress,ethAmount,tokenAmount,dealEthAmount,dealTokenAmount,blockNum,serviceCharge
                       **/
                      function find(address start, uint256 count, uint256 maxFindCount, address owner) view public returns (string memory) {
                          
                          // Buffer array used to generate result string
                          bytes memory buf = new bytes(500000);
                          uint256 index = 0;
                          
                          // Calculate search interval i and end
                          uint256 i = _prices.length;
                          uint256 end = 0;
                          if (start != address(0)) {
                              i = toIndex(start);
                          }
                          if (i > maxFindCount) {
                              end = i - maxFindCount;
                          }
                          
                          // Loop search, write qualified records into buffer
                          while (count > 0 && i-- > end) {
                              Nest_3_OfferPriceData memory price = _prices[i];
                              if (price.owner == owner) {
                                  --count;
                                  index = writeOfferPriceData(i, price, buf, index);
                              }
                          }
                          
                          // Generate result string and return
                          bytes memory str = new bytes(index);
                          while(index-- > 0) {
                              str[index] = buf[index];
                          }
                          return string(str);
                      }
                      
                      /**
                       * Get the list of offers by page
                       * @param offset Skip the first offset records
                       * @param count Maximum number of records to return
                       * @param order Sort rules. 0 means reverse order, non-zero means positive order
                       * @return Separate the offer records with symbols. use , to divide fields: 
                       * uuid,owner,tokenAddress,ethAmount,tokenAmount,dealEthAmount,dealTokenAmount,blockNum,serviceCharge
                       **/
                      function list(uint256 offset, uint256 count, uint256 order) view public returns (string memory) {
                          
                          // Buffer array used to generate result string
                          bytes memory buf = new bytes(500000);
                          uint256 index = 0;
                          
                          // Find search interval i and end
                          uint256 i = 0;
                          uint256 end = 0;
                          
                          if (order == 0) {
                              // Reverse order, in default 
                              // Calculate search interval i and end
                              if (offset < _prices.length) {
                                  i = _prices.length - offset;
                              } 
                              if (count < i) {
                                  end = i - count;
                              }
                              
                              // Write records in the target interval into the buffer
                              while (i-- > end) {
                                  index = writeOfferPriceData(i, _prices[i], buf, index);
                              }
                          } else {
                              // Ascending order
                              // Calculate the search interval i and end
                              if (offset < _prices.length) {
                                  i = offset;
                              } else {
                                  i = _prices.length;
                              }
                              end = i + count;
                              if(end > _prices.length) {
                                  end = _prices.length;
                              }
                              
                              // Write the records in the target interval into the buffer
                              while (i < end) {
                                  index = writeOfferPriceData(i, _prices[i], buf, index);
                                  ++i;
                              }
                          }
                          
                          // Generate the result string and return
                          bytes memory str = new bytes(index);
                          while(index-- > 0) {
                              str[index] = buf[index];
                          }
                          return string(str);
                      }   
                       
                      // Write the offer data into the buffer and return the buffer index
                      function writeOfferPriceData(uint256 priceIndex, Nest_3_OfferPriceData memory price, bytes memory buf, uint256 index) pure private returns (uint256) {
                          index = writeAddress(toAddress(priceIndex), buf, index);
                          buf[index++] = byte(uint8(44));
                          
                          index = writeAddress(price.owner, buf, index);
                          buf[index++] = byte(uint8(44));
                          
                          index = writeAddress(price.tokenAddress, buf, index);
                          buf[index++] = byte(uint8(44));
                          
                          index = writeUInt(price.ethAmount, buf, index);
                          buf[index++] = byte(uint8(44));
                          
                          index = writeUInt(price.tokenAmount, buf, index);
                          buf[index++] = byte(uint8(44));
                         
                          index = writeUInt(price.dealEthAmount, buf, index);
                          buf[index++] = byte(uint8(44));
                          
                          index = writeUInt(price.dealTokenAmount, buf, index);
                          buf[index++] = byte(uint8(44));
                          
                          index = writeUInt(price.blockNum, buf, index);
                          buf[index++] = byte(uint8(44));
                          
                          index = writeUInt(price.serviceCharge, buf, index);
                          buf[index++] = byte(uint8(44));
                          
                          return index;
                      }
                       
                      // Convert integer to string in decimal form and write it into the buffer, and return the buffer index
                      function writeUInt(uint256 iv, bytes memory buf, uint256 index) pure public returns (uint256) {
                          uint256 i = index;
                          do {
                              buf[index++] = byte(uint8(iv % 10 +48));
                              iv /= 10;
                          } while (iv > 0);
                          
                          for (uint256 j = index; j > i; ++i) {
                              byte t = buf[i];
                              buf[i] = buf[--j];
                              buf[j] = t;
                          }
                          
                          return index;
                      }
                  
                      // Convert the address to a hexadecimal string and write it into the buffer, and return the buffer index
                      function writeAddress(address addr, bytes memory buf, uint256 index) pure private returns (uint256) {
                          
                          uint256 iv = uint256(addr);
                          uint256 i = index + 40;
                          do {
                              uint256 w = iv % 16;
                              if(w < 10) {
                                  buf[index++] = byte(uint8(w +48));
                              } else {
                                  buf[index++] = byte(uint8(w +87));
                              }
                              
                              iv /= 16;
                          } while (index < i);
                          
                          i -= 40;
                          for (uint256 j = index; j > i; ++i) {
                              byte t = buf[i];
                              buf[i] = buf[--j];
                              buf[j] = t;
                          }
                          
                          return index;
                      }
                      
                      // Vote administrator only
                      modifier onlyOwner(){
                          require(_voteFactory.checkOwners(msg.sender), "No authority");
                          _;
                      }
                  }
                  
                  // NestNode assignment contract
                  interface Nest_NodeAssignment {
                      function bookKeeping(uint256 amount) external;
                  }
                  
                  // Mining pool logic
                  interface Nest_3_MiningContract {
                      // Offering mining
                      function oreDrawing() external returns (uint256);
                  }
                  
                  // Voting contract
                  interface Nest_3_VoteFactory {
                      // Check address
                  	function checkAddress(string calldata name) external view returns (address contractAddress);
                  	// Check whether administrator
                  	function checkOwners(address man) external view returns (bool);
                  }
                  
                  // Price contract
                  interface Nest_3_OfferPrice {
                      function addPrice(uint256 ethAmount, uint256 tokenAmount, uint256 endBlock, address tokenAddress, address offerOwner) external;
                      function changePrice(uint256 ethAmount, uint256 tokenAmount, address tokenAddress, uint256 endBlock) external;
                      function updateAndCheckPricePrivate(address tokenAddress) external view returns(uint256 ethAmount, uint256 erc20Amount);
                  }
                  
                  // Bonus pool contract
                  interface Nest_3_Abonus {
                      function switchToEth(address token) external payable;
                  }
                  
                  
                  library SafeMath {
                      function add(uint256 a, uint256 b) internal pure returns (uint256) {
                          uint256 c = a + b;
                          require(c >= a, "SafeMath: addition overflow");
                  
                          return c;
                      }
                      function sub(uint256 a, uint256 b) internal pure returns (uint256) {
                          return sub(a, b, "SafeMath: subtraction overflow");
                      }
                      function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
                          require(b <= a, errorMessage);
                          uint256 c = a - b;
                  
                          return c;
                      }
                      function mul(uint256 a, uint256 b) internal pure returns (uint256) {
                          if (a == 0) {
                              return 0;
                          }
                          uint256 c = a * b;
                          require(c / a == b, "SafeMath: multiplication overflow");
                  
                          return c;
                      }
                      function div(uint256 a, uint256 b) internal pure returns (uint256) {
                          return div(a, b, "SafeMath: division by zero");
                      }
                      function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
                          require(b > 0, errorMessage);
                          uint256 c = a / b;
                          return c;
                      }
                      function mod(uint256 a, uint256 b) internal pure returns (uint256) {
                          return mod(a, b, "SafeMath: modulo by zero");
                      }
                      function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
                          require(b != 0, errorMessage);
                          return a % b;
                      }
                  }
                  
                  library address_make_payable {
                     function make_payable(address x) internal pure returns (address payable) {
                        return address(uint160(x));
                     }
                  }
                  
                  library SafeERC20 {
                      using SafeMath for uint256;
                      using Address for address;
                  
                      function safeTransfer(ERC20 token, address to, uint256 value) internal {
                          callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
                      }
                  
                      function safeTransferFrom(ERC20 token, address from, address to, uint256 value) internal {
                          callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
                      }
                  
                      function safeApprove(ERC20 token, address spender, uint256 value) internal {
                          require((value == 0) || (token.allowance(address(this), spender) == 0),
                              "SafeERC20: approve from non-zero to non-zero allowance"
                          );
                          callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
                      }
                  
                      function safeIncreaseAllowance(ERC20 token, address spender, uint256 value) internal {
                          uint256 newAllowance = token.allowance(address(this), spender).add(value);
                          callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
                      }
                  
                      function safeDecreaseAllowance(ERC20 token, address spender, uint256 value) internal {
                          uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
                          callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
                      }
                      function callOptionalReturn(ERC20 token, bytes memory data) private {
                          require(address(token).isContract(), "SafeERC20: call to non-contract");
                          (bool success, bytes memory returndata) = address(token).call(data);
                          require(success, "SafeERC20: low-level call failed");
                          if (returndata.length > 0) {
                              require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
                          }
                      }
                  }
                  
                  interface ERC20 {
                      function totalSupply() external view returns (uint256);
                      function balanceOf(address account) external view returns (uint256);
                      function transfer(address recipient, uint256 amount) external returns (bool);
                      function allowance(address owner, address spender) external view returns (uint256);
                      function approve(address spender, uint256 amount) external returns (bool);
                      function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
                      event Transfer(address indexed from, address indexed to, uint256 value);
                      event Approval(address indexed owner, address indexed spender, uint256 value);
                  }
                  
                  library Address {
                      function isContract(address account) internal view returns (bool) {
                          bytes32 codehash;
                          bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
                          assembly { codehash := extcodehash(account) }
                          return (codehash != accountHash && codehash != 0x0);
                      }
                      function sendValue(address payable recipient, uint256 amount) internal {
                          require(address(this).balance >= amount, "Address: insufficient balance");
                          (bool success, ) = recipient.call.value(amount)("");
                          require(success, "Address: unable to send value, recipient may have reverted");
                      }
                  }

                  File 2 of 11: TetherToken
                  pragma solidity ^0.4.17;
                  
                  /**
                   * @title SafeMath
                   * @dev Math operations with safety checks that throw on error
                   */
                  library SafeMath {
                      function mul(uint256 a, uint256 b) internal pure returns (uint256) {
                          if (a == 0) {
                              return 0;
                          }
                          uint256 c = a * b;
                          assert(c / a == b);
                          return c;
                      }
                  
                      function div(uint256 a, uint256 b) internal pure returns (uint256) {
                          // assert(b > 0); // Solidity automatically throws when dividing by 0
                          uint256 c = a / b;
                          // assert(a == b * c + a % b); // There is no case in which this doesn't hold
                          return c;
                      }
                  
                      function sub(uint256 a, uint256 b) internal pure returns (uint256) {
                          assert(b <= a);
                          return a - b;
                      }
                  
                      function add(uint256 a, uint256 b) internal pure returns (uint256) {
                          uint256 c = a + b;
                          assert(c >= a);
                          return c;
                      }
                  }
                  
                  /**
                   * @title Ownable
                   * @dev The Ownable contract has an owner address, and provides basic authorization control
                   * functions, this simplifies the implementation of "user permissions".
                   */
                  contract Ownable {
                      address public owner;
                  
                      /**
                        * @dev The Ownable constructor sets the original `owner` of the contract to the sender
                        * account.
                        */
                      function Ownable() public {
                          owner = msg.sender;
                      }
                  
                      /**
                        * @dev Throws if called by any account other than the owner.
                        */
                      modifier onlyOwner() {
                          require(msg.sender == owner);
                          _;
                      }
                  
                      /**
                      * @dev Allows the current owner to transfer control of the contract to a newOwner.
                      * @param newOwner The address to transfer ownership to.
                      */
                      function transferOwnership(address newOwner) public onlyOwner {
                          if (newOwner != address(0)) {
                              owner = newOwner;
                          }
                      }
                  
                  }
                  
                  /**
                   * @title ERC20Basic
                   * @dev Simpler version of ERC20 interface
                   * @dev see https://github.com/ethereum/EIPs/issues/20
                   */
                  contract ERC20Basic {
                      uint public _totalSupply;
                      function totalSupply() public constant returns (uint);
                      function balanceOf(address who) public constant returns (uint);
                      function transfer(address to, uint value) public;
                      event Transfer(address indexed from, address indexed to, uint value);
                  }
                  
                  /**
                   * @title ERC20 interface
                   * @dev see https://github.com/ethereum/EIPs/issues/20
                   */
                  contract ERC20 is ERC20Basic {
                      function allowance(address owner, address spender) public constant returns (uint);
                      function transferFrom(address from, address to, uint value) public;
                      function approve(address spender, uint value) public;
                      event Approval(address indexed owner, address indexed spender, uint value);
                  }
                  
                  /**
                   * @title Basic token
                   * @dev Basic version of StandardToken, with no allowances.
                   */
                  contract BasicToken is Ownable, ERC20Basic {
                      using SafeMath for uint;
                  
                      mapping(address => uint) public balances;
                  
                      // additional variables for use if transaction fees ever became necessary
                      uint public basisPointsRate = 0;
                      uint public maximumFee = 0;
                  
                      /**
                      * @dev Fix for the ERC20 short address attack.
                      */
                      modifier onlyPayloadSize(uint size) {
                          require(!(msg.data.length < size + 4));
                          _;
                      }
                  
                      /**
                      * @dev transfer token for a specified address
                      * @param _to The address to transfer to.
                      * @param _value The amount to be transferred.
                      */
                      function transfer(address _to, uint _value) public onlyPayloadSize(2 * 32) {
                          uint fee = (_value.mul(basisPointsRate)).div(10000);
                          if (fee > maximumFee) {
                              fee = maximumFee;
                          }
                          uint sendAmount = _value.sub(fee);
                          balances[msg.sender] = balances[msg.sender].sub(_value);
                          balances[_to] = balances[_to].add(sendAmount);
                          if (fee > 0) {
                              balances[owner] = balances[owner].add(fee);
                              Transfer(msg.sender, owner, fee);
                          }
                          Transfer(msg.sender, _to, sendAmount);
                      }
                  
                      /**
                      * @dev Gets the balance of the specified address.
                      * @param _owner The address to query the the balance of.
                      * @return An uint representing the amount owned by the passed address.
                      */
                      function balanceOf(address _owner) public constant returns (uint balance) {
                          return balances[_owner];
                      }
                  
                  }
                  
                  /**
                   * @title Standard ERC20 token
                   *
                   * @dev Implementation of the basic standard token.
                   * @dev https://github.com/ethereum/EIPs/issues/20
                   * @dev Based oncode by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
                   */
                  contract StandardToken is BasicToken, ERC20 {
                  
                      mapping (address => mapping (address => uint)) public allowed;
                  
                      uint public constant MAX_UINT = 2**256 - 1;
                  
                      /**
                      * @dev Transfer tokens from one address to another
                      * @param _from address The address which you want to send tokens from
                      * @param _to address The address which you want to transfer to
                      * @param _value uint the amount of tokens to be transferred
                      */
                      function transferFrom(address _from, address _to, uint _value) public onlyPayloadSize(3 * 32) {
                          var _allowance = allowed[_from][msg.sender];
                  
                          // Check is not needed because sub(_allowance, _value) will already throw if this condition is not met
                          // if (_value > _allowance) throw;
                  
                          uint fee = (_value.mul(basisPointsRate)).div(10000);
                          if (fee > maximumFee) {
                              fee = maximumFee;
                          }
                          if (_allowance < MAX_UINT) {
                              allowed[_from][msg.sender] = _allowance.sub(_value);
                          }
                          uint sendAmount = _value.sub(fee);
                          balances[_from] = balances[_from].sub(_value);
                          balances[_to] = balances[_to].add(sendAmount);
                          if (fee > 0) {
                              balances[owner] = balances[owner].add(fee);
                              Transfer(_from, owner, fee);
                          }
                          Transfer(_from, _to, sendAmount);
                      }
                  
                      /**
                      * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
                      * @param _spender The address which will spend the funds.
                      * @param _value The amount of tokens to be spent.
                      */
                      function approve(address _spender, uint _value) public onlyPayloadSize(2 * 32) {
                  
                          // To change the approve amount you first have to reduce the addresses`
                          //  allowance to zero by calling `approve(_spender, 0)` if it is not
                          //  already 0 to mitigate the race condition described here:
                          //  https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
                          require(!((_value != 0) && (allowed[msg.sender][_spender] != 0)));
                  
                          allowed[msg.sender][_spender] = _value;
                          Approval(msg.sender, _spender, _value);
                      }
                  
                      /**
                      * @dev Function to check the amount of tokens than an owner allowed to a spender.
                      * @param _owner address The address which owns the funds.
                      * @param _spender address The address which will spend the funds.
                      * @return A uint specifying the amount of tokens still available for the spender.
                      */
                      function allowance(address _owner, address _spender) public constant returns (uint remaining) {
                          return allowed[_owner][_spender];
                      }
                  
                  }
                  
                  
                  /**
                   * @title Pausable
                   * @dev Base contract which allows children to implement an emergency stop mechanism.
                   */
                  contract Pausable is Ownable {
                    event Pause();
                    event Unpause();
                  
                    bool public paused = false;
                  
                  
                    /**
                     * @dev Modifier to make a function callable only when the contract is not paused.
                     */
                    modifier whenNotPaused() {
                      require(!paused);
                      _;
                    }
                  
                    /**
                     * @dev Modifier to make a function callable only when the contract is paused.
                     */
                    modifier whenPaused() {
                      require(paused);
                      _;
                    }
                  
                    /**
                     * @dev called by the owner to pause, triggers stopped state
                     */
                    function pause() onlyOwner whenNotPaused public {
                      paused = true;
                      Pause();
                    }
                  
                    /**
                     * @dev called by the owner to unpause, returns to normal state
                     */
                    function unpause() onlyOwner whenPaused public {
                      paused = false;
                      Unpause();
                    }
                  }
                  
                  contract BlackList is Ownable, BasicToken {
                  
                      /////// Getters to allow the same blacklist to be used also by other contracts (including upgraded Tether) ///////
                      function getBlackListStatus(address _maker) external constant returns (bool) {
                          return isBlackListed[_maker];
                      }
                  
                      function getOwner() external constant returns (address) {
                          return owner;
                      }
                  
                      mapping (address => bool) public isBlackListed;
                      
                      function addBlackList (address _evilUser) public onlyOwner {
                          isBlackListed[_evilUser] = true;
                          AddedBlackList(_evilUser);
                      }
                  
                      function removeBlackList (address _clearedUser) public onlyOwner {
                          isBlackListed[_clearedUser] = false;
                          RemovedBlackList(_clearedUser);
                      }
                  
                      function destroyBlackFunds (address _blackListedUser) public onlyOwner {
                          require(isBlackListed[_blackListedUser]);
                          uint dirtyFunds = balanceOf(_blackListedUser);
                          balances[_blackListedUser] = 0;
                          _totalSupply -= dirtyFunds;
                          DestroyedBlackFunds(_blackListedUser, dirtyFunds);
                      }
                  
                      event DestroyedBlackFunds(address _blackListedUser, uint _balance);
                  
                      event AddedBlackList(address _user);
                  
                      event RemovedBlackList(address _user);
                  
                  }
                  
                  contract UpgradedStandardToken is StandardToken{
                      // those methods are called by the legacy contract
                      // and they must ensure msg.sender to be the contract address
                      function transferByLegacy(address from, address to, uint value) public;
                      function transferFromByLegacy(address sender, address from, address spender, uint value) public;
                      function approveByLegacy(address from, address spender, uint value) public;
                  }
                  
                  contract TetherToken is Pausable, StandardToken, BlackList {
                  
                      string public name;
                      string public symbol;
                      uint public decimals;
                      address public upgradedAddress;
                      bool public deprecated;
                  
                      //  The contract can be initialized with a number of tokens
                      //  All the tokens are deposited to the owner address
                      //
                      // @param _balance Initial supply of the contract
                      // @param _name Token Name
                      // @param _symbol Token symbol
                      // @param _decimals Token decimals
                      function TetherToken(uint _initialSupply, string _name, string _symbol, uint _decimals) public {
                          _totalSupply = _initialSupply;
                          name = _name;
                          symbol = _symbol;
                          decimals = _decimals;
                          balances[owner] = _initialSupply;
                          deprecated = false;
                      }
                  
                      // Forward ERC20 methods to upgraded contract if this one is deprecated
                      function transfer(address _to, uint _value) public whenNotPaused {
                          require(!isBlackListed[msg.sender]);
                          if (deprecated) {
                              return UpgradedStandardToken(upgradedAddress).transferByLegacy(msg.sender, _to, _value);
                          } else {
                              return super.transfer(_to, _value);
                          }
                      }
                  
                      // Forward ERC20 methods to upgraded contract if this one is deprecated
                      function transferFrom(address _from, address _to, uint _value) public whenNotPaused {
                          require(!isBlackListed[_from]);
                          if (deprecated) {
                              return UpgradedStandardToken(upgradedAddress).transferFromByLegacy(msg.sender, _from, _to, _value);
                          } else {
                              return super.transferFrom(_from, _to, _value);
                          }
                      }
                  
                      // Forward ERC20 methods to upgraded contract if this one is deprecated
                      function balanceOf(address who) public constant returns (uint) {
                          if (deprecated) {
                              return UpgradedStandardToken(upgradedAddress).balanceOf(who);
                          } else {
                              return super.balanceOf(who);
                          }
                      }
                  
                      // Forward ERC20 methods to upgraded contract if this one is deprecated
                      function approve(address _spender, uint _value) public onlyPayloadSize(2 * 32) {
                          if (deprecated) {
                              return UpgradedStandardToken(upgradedAddress).approveByLegacy(msg.sender, _spender, _value);
                          } else {
                              return super.approve(_spender, _value);
                          }
                      }
                  
                      // Forward ERC20 methods to upgraded contract if this one is deprecated
                      function allowance(address _owner, address _spender) public constant returns (uint remaining) {
                          if (deprecated) {
                              return StandardToken(upgradedAddress).allowance(_owner, _spender);
                          } else {
                              return super.allowance(_owner, _spender);
                          }
                      }
                  
                      // deprecate current contract in favour of a new one
                      function deprecate(address _upgradedAddress) public onlyOwner {
                          deprecated = true;
                          upgradedAddress = _upgradedAddress;
                          Deprecate(_upgradedAddress);
                      }
                  
                      // deprecate current contract if favour of a new one
                      function totalSupply() public constant returns (uint) {
                          if (deprecated) {
                              return StandardToken(upgradedAddress).totalSupply();
                          } else {
                              return _totalSupply;
                          }
                      }
                  
                      // Issue a new amount of tokens
                      // these tokens are deposited into the owner address
                      //
                      // @param _amount Number of tokens to be issued
                      function issue(uint amount) public onlyOwner {
                          require(_totalSupply + amount > _totalSupply);
                          require(balances[owner] + amount > balances[owner]);
                  
                          balances[owner] += amount;
                          _totalSupply += amount;
                          Issue(amount);
                      }
                  
                      // Redeem tokens.
                      // These tokens are withdrawn from the owner address
                      // if the balance must be enough to cover the redeem
                      // or the call will fail.
                      // @param _amount Number of tokens to be issued
                      function redeem(uint amount) public onlyOwner {
                          require(_totalSupply >= amount);
                          require(balances[owner] >= amount);
                  
                          _totalSupply -= amount;
                          balances[owner] -= amount;
                          Redeem(amount);
                      }
                  
                      function setParams(uint newBasisPoints, uint newMaxFee) public onlyOwner {
                          // Ensure transparency by hardcoding limit beyond which fees can never be added
                          require(newBasisPoints < 20);
                          require(newMaxFee < 50);
                  
                          basisPointsRate = newBasisPoints;
                          maximumFee = newMaxFee.mul(10**decimals);
                  
                          Params(basisPointsRate, maximumFee);
                      }
                  
                      // Called when new token are issued
                      event Issue(uint amount);
                  
                      // Called when tokens are redeemed
                      event Redeem(uint amount);
                  
                      // Called when contract is deprecated
                      event Deprecate(address newAddress);
                  
                      // Called if contract ever adds fees
                      event Params(uint feeBasisPoints, uint maxFee);
                  }

                  File 3 of 11: Nest_3_MiningContract
                  pragma solidity 0.6.0;
                  
                  /**
                   * @title Mining contract
                   * @dev Mining pool + mining logic
                   */
                  contract Nest_3_MiningContract {
                      
                      using address_make_payable for address;
                      using SafeMath for uint256;
                      
                      uint256 _blockAttenuation = 2400000;                 //  Block decay time interval
                      uint256[10] _attenuationAmount;                      //  Mining decay amount
                      uint256 _afterMiningAmount = 40 ether;               //  Stable period mining amount
                      uint256 _firstBlockNum;                              //  Starting mining block
                      uint256 _latestMining;                               //  Latest offering block
                      Nest_3_VoteFactory _voteFactory;                     //  Voting contract
                      ERC20 _nestContract;                                 //  NEST contract address
                      address _offerFactoryAddress;                        //  Offering contract address
                      
                      // Current block, current block mining amount
                      event OreDrawingLog(uint256 nowBlock, uint256 blockAmount);
                      
                      /**
                      * @dev Initialization method
                      * @param voteFactory  voting contract address
                      */
                      constructor(address voteFactory) public {
                          _voteFactory = Nest_3_VoteFactory(address(voteFactory));                  
                          _offerFactoryAddress = address(_voteFactory.checkAddress("nest.v3.offerMain"));
                          _nestContract = ERC20(address(_voteFactory.checkAddress("nest")));
                          // Initiate mining parameters
                          _firstBlockNum = 6236588;
                          _latestMining = block.number;
                          uint256 blockAmount = 400 ether;
                          for (uint256 i = 0; i < 10; i ++) {
                              _attenuationAmount[i] = blockAmount;
                              blockAmount = blockAmount.mul(8).div(10);
                          }
                      }
                      
                      /**
                      * @dev Reset voting contract
                      * @param voteFactory Voting contract address
                      */
                      function changeMapping(address voteFactory) public onlyOwner {
                          _voteFactory = Nest_3_VoteFactory(address(voteFactory));                  
                          _offerFactoryAddress = address(_voteFactory.checkAddress("nest.v3.offerMain"));
                          _nestContract = ERC20(address(_voteFactory.checkAddress("nest")));
                      }
                      
                      /**
                      * @dev Offering mining
                      * @return Current block mining amount
                      */
                      function oreDrawing() public returns (uint256) {
                          require(address(msg.sender) == _offerFactoryAddress, "No authority");
                          //  Update mining amount list
                          uint256 miningAmount = changeBlockAmountList();
                          //  Transfer NEST
                          if (_nestContract.balanceOf(address(this)) < miningAmount){
                              miningAmount = _nestContract.balanceOf(address(this));
                          }
                          if (miningAmount > 0) {
                              _nestContract.transfer(address(msg.sender), miningAmount);
                              emit OreDrawingLog(block.number,miningAmount);
                          }
                          return miningAmount;
                      }
                      
                      /**
                      * @dev Update mining amount list
                      */
                      function changeBlockAmountList() private returns (uint256) {
                          uint256 createBlock = _firstBlockNum;
                          uint256 recentlyUsedBlock = _latestMining;
                          uint256 attenuationPointNow = block.number.sub(createBlock).div(_blockAttenuation);
                          uint256 miningAmount = 0;
                          uint256 attenuation;
                          if (attenuationPointNow > 9) {
                              attenuation = _afterMiningAmount;
                          } else {
                              attenuation = _attenuationAmount[attenuationPointNow];
                          }
                          miningAmount = attenuation.mul(block.number.sub(recentlyUsedBlock));
                          _latestMining = block.number;
                          return miningAmount;
                      }
                      
                      /**
                      * @dev Transfer all NEST
                      * @param target Transfer target address
                      */
                      function takeOutNest(address target) public onlyOwner {
                          _nestContract.transfer(address(target),_nestContract.balanceOf(address(this)));
                      }
                  
                      // Check block decay time interval
                      function checkBlockAttenuation() public view returns(uint256) {
                          return _blockAttenuation;
                      }
                      
                      // Check latest offering block
                      function checkLatestMining() public view returns(uint256) {
                          return _latestMining;
                      }
                      
                      // Check mining amount decay
                      function checkAttenuationAmount(uint256 num) public view returns(uint256) {
                          return _attenuationAmount[num];
                      }
                      
                      // Check NEST balance
                      function checkNestBalance() public view returns(uint256) {
                          return _nestContract.balanceOf(address(this));
                      }
                      
                      // Modify block decay time interval
                      function changeBlockAttenuation(uint256 blockNum) public onlyOwner {
                          require(blockNum > 0);
                          _blockAttenuation = blockNum;
                      }
                      
                      // Modify mining amount decay
                      function changeAttenuationAmount(uint256 firstAmount, uint256 top, uint256 bottom) public onlyOwner {
                          uint256 blockAmount = firstAmount;
                          for (uint256 i = 0; i < 10; i ++) {
                              _attenuationAmount[i] = blockAmount;
                              blockAmount = blockAmount.mul(top).div(bottom);
                          }
                      }
                      
                      // Administrator only
                      modifier onlyOwner(){
                          require(_voteFactory.checkOwners(msg.sender), "No authority");
                          _;
                      }
                  }
                  
                  // Voting contract
                  interface Nest_3_VoteFactory {
                      // Check address
                  	function checkAddress(string calldata name) external view returns (address contractAddress);
                  	// Check whether administrator
                  	function checkOwners(address man) external view returns (bool);
                  }
                  
                  // EC20
                  interface ERC20 {
                      function totalSupply() external view returns (uint256);
                      function balanceOf(address account) external view returns (uint256);
                      function transfer(address recipient, uint256 amount) external returns (bool);
                      function allowance(address owner, address spender) external view returns (uint256);
                      function approve(address spender, uint256 amount) external returns (bool);
                      function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
                      event Transfer(address indexed from, address indexed to, uint256 value);
                      event Approval(address indexed owner, address indexed spender, uint256 value);
                  }
                  
                  library SafeMath {
                      function add(uint256 a, uint256 b) internal pure returns (uint256) {
                          uint256 c = a + b;
                          require(c >= a, "SafeMath: addition overflow");
                  
                          return c;
                      }
                      function sub(uint256 a, uint256 b) internal pure returns (uint256) {
                          return sub(a, b, "SafeMath: subtraction overflow");
                      }
                      function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
                          require(b <= a, errorMessage);
                          uint256 c = a - b;
                  
                          return c;
                      }
                      function mul(uint256 a, uint256 b) internal pure returns (uint256) {
                          if (a == 0) {
                              return 0;
                          }
                          uint256 c = a * b;
                          require(c / a == b, "SafeMath: multiplication overflow");
                  
                          return c;
                      }
                      function div(uint256 a, uint256 b) internal pure returns (uint256) {
                          return div(a, b, "SafeMath: division by zero");
                      }
                      function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
                          require(b > 0, errorMessage);
                          uint256 c = a / b;
                          return c;
                      }
                      function mod(uint256 a, uint256 b) internal pure returns (uint256) {
                          return mod(a, b, "SafeMath: modulo by zero");
                      }
                      function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
                          require(b != 0, errorMessage);
                          return a % b;
                      }
                  }
                  
                  library address_make_payable {
                     function make_payable(address x) internal pure returns (address payable) {
                        return address(uint160(x));
                     }
                  }

                  File 4 of 11: IBNEST
                  pragma solidity ^0.5.1;
                  
                  library IterableMapping {
                    struct itmap
                    {
                      mapping(address => IndexValue) data;
                      KeyFlag[] keys;
                      uint size;
                    }
                    struct IndexValue { uint keyIndex; uint value; }
                    struct KeyFlag { address key; bool deleted; }
                    function insert(itmap storage self, address key, uint value) public returns (bool replaced)
                    {
                      uint keyIndex = self.data[key].keyIndex;
                      self.data[key].value = value;
                      if (keyIndex > 0)
                        return true;
                      else
                      {
                        keyIndex = self.keys.length++;
                        self.data[key].keyIndex = keyIndex + 1;
                        self.keys[keyIndex].key = key;
                        self.size++;
                        return false;
                      }
                    }
                    function remove(itmap storage self, address key) public returns (bool success)
                    {
                      uint keyIndex = self.data[key].keyIndex;
                      if (keyIndex == 0)
                        return false;
                      delete self.data[key];
                      self.keys[keyIndex - 1].deleted = true;
                      self.size --;
                    }
                    function contains(itmap storage self, address key) public view returns (bool)
                    {
                      return self.data[key].keyIndex > 0;
                    }
                    function iterate_start(itmap storage self) public view returns (uint keyIndex)
                    {
                      return iterate_next(self, uint(-1));
                    }
                    function iterate_valid(itmap storage self, uint keyIndex) public view returns (bool)
                    {
                      return keyIndex < self.keys.length;
                    }
                    function iterate_next(itmap storage self, uint keyIndex) public view returns (uint r_keyIndex)
                    {
                      keyIndex++;
                      while (keyIndex < self.keys.length && self.keys[keyIndex].deleted)
                        keyIndex++;
                      return keyIndex;
                    }
                    function iterate_get(itmap storage self, uint keyIndex) public view returns (address key, uint value)
                    {
                      key = self.keys[keyIndex].key;
                      value = self.data[key].value;
                    }
                    function iterate_getValue(itmap storage self, address key) public view returns (uint value) {
                        return self.data[key].value;
                    }
                  }
                  
                  /**
                   * @title SafeMath
                   * @dev Math operations with safety checks that throw on error
                   */
                  library SafeMath {
                  
                    /**
                    * @dev Multiplies two numbers, throws on overflow.
                    */
                    function mul(uint256 _a, uint256 _b) internal pure returns (uint256 c) {
                      // Gas optimization: this is cheaper than asserting 'a' not being zero, but the
                      // benefit is lost if 'b' is also tested.
                      // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
                      if (_a == 0) {
                        return 0;
                      }
                  
                      c = _a * _b;
                      assert(c / _a == _b);
                      return c;
                    }
                  
                    /**
                    * @dev Integer division of two numbers, truncating the quotient.
                    */
                    function div(uint256 _a, uint256 _b) internal pure returns (uint256) {
                      assert(_b > 0); // Solidity automatically throws when dividing by 0
                      uint256 c = _a / _b;
                      assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold
                      return _a / _b;
                    }
                  
                    /**
                    * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
                    */
                    function sub(uint256 _a, uint256 _b) internal pure returns (uint256) {
                      assert(_b <= _a);
                      return _a - _b;
                    }
                  
                    /**
                    * @dev Adds two numbers, throws on overflow.
                    */
                    function add(uint256 _a, uint256 _b) internal pure returns (uint256 c) {
                      c = _a + _b;
                      assert(c >= _a);
                      return c;
                    }
                  }
                  
                  /**
                   * @title ERC20Basic
                   * @dev Simpler version of ERC20 interface
                   * See https://github.com/ethereum/EIPs/issues/179
                   */
                  contract ERC20Basic {
                    function totalSupply() public view returns (uint256);
                    function balanceOf(address _who) public view returns (uint256);
                    function transfer(address _to, uint256 _value) public returns (bool);
                    event Transfer(address indexed from, address indexed to, uint256 value);
                  }
                  
                  
                  /**
                   * @title Basic token
                   * @dev Basic version of StandardToken, with no allowances.
                   */
                  contract BasicToken is ERC20Basic {
                    using SafeMath for uint256;
                    IterableMapping.itmap balances;
                  
                    uint256 internal totalSupply_;
                  
                    /**
                    * @dev Total number of tokens in existence
                    */
                    function totalSupply() public view returns (uint256) {
                      return totalSupply_;
                    }
                  
                    /**
                    * @dev Transfer token for a specified address
                    * @param _to The address to transfer to.
                    * @param _value The amount to be transferred.
                    */
                    function transfer(address _to, uint256 _value) public returns (bool) {
                        
                      require(_value <= IterableMapping.iterate_getValue(balances, msg.sender));
                      require(_to != address(0));
                      
                      IterableMapping.insert(balances, msg.sender, IterableMapping.iterate_getValue(balances, msg.sender).sub(_value));
                      IterableMapping.insert(balances, _to, IterableMapping.iterate_getValue(balances, _to).add(_value));
                      emit Transfer(msg.sender, _to, _value);
                      return true;
                    }
                  
                    /**
                    * @dev Gets the balance of the specified address.
                    * @param _owner The address to query the the balance of.
                    * @return An uint256 representing the amount owned by the passed address.
                    */
                    function balanceOf(address _owner) public view returns (uint256) {
                        return IterableMapping.iterate_getValue(balances, _owner);
                    }
                  
                  }
                  
                  
                  
                  /**
                   * @title ERC20 interface
                   * @dev see https://github.com/ethereum/EIPs/issues/20
                   */
                  contract ERC20 is ERC20Basic {
                    function allowance(address _owner, address _spender)
                      public view returns (uint256);
                  
                    function transferFrom(address _from, address _to, uint256 _value)
                      public returns (bool);
                  
                    function approve(address _spender, uint256 _value) public returns (bool);
                    event Approval(
                      address indexed owner,
                      address indexed spender,
                      uint256 value
                    );
                  }
                  
                  /**
                   * @title Standard ERC20 token
                   *
                   * @dev Implementation of the basic standard token.
                   * https://github.com/ethereum/EIPs/issues/20
                   * Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
                   */
                  contract StandardToken is ERC20, BasicToken {
                  
                    mapping (address => mapping (address => uint256)) internal allowed;
                  
                  
                    /**
                     * @dev Transfer tokens from one address to another
                     * @param _from address The address which you want to send tokens from
                     * @param _to address The address which you want to transfer to
                     * @param _value uint256 the amount of tokens to be transferred
                     */
                    function transferFrom(
                      address _from,
                      address _to,
                      uint256 _value
                    )
                      public
                      returns (bool)
                    {
                        
                      require(_value <= IterableMapping.iterate_getValue(balances, _from));
                  
                      require(_value <= allowed[_from][msg.sender]);
                      require(_to != address(0));
                  
                      IterableMapping.insert(balances, _from, IterableMapping.iterate_getValue(balances, _from).sub(_value));
                      IterableMapping.insert(balances, _to, IterableMapping.iterate_getValue(balances, _to).add(_value));
                  
                      allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
                      emit Transfer(_from, _to, _value);
                      return true;
                    }
                  
                    /**
                     * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
                     * Beware that changing an allowance with this method brings the risk that someone may use both the old
                     * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
                     * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
                     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
                     * @param _spender The address which will spend the funds.
                     * @param _value The amount of tokens to be spent.
                     */
                    function approve(address _spender, uint256 _value) public returns (bool) {
                      allowed[msg.sender][_spender] = _value;
                      emit Approval(msg.sender, _spender, _value);
                      return true;
                    }
                  
                    /**
                     * @dev Function to check the amount of tokens that an owner allowed to a spender.
                     * @param _owner address The address which owns the funds.
                     * @param _spender address The address which will spend the funds.
                     * @return A uint256 specifying the amount of tokens still available for the spender.
                     */
                    function allowance(
                      address _owner,
                      address _spender
                     )
                      public
                      view
                      returns (uint256)
                    {
                      return allowed[_owner][_spender];
                    }
                  
                    /**
                     * @dev Increase the amount of tokens that an owner allowed to a spender.
                     * approve should be called when allowed[_spender] == 0. To increment
                     * allowed value is better to use this function to avoid 2 calls (and wait until
                     * the first transaction is mined)
                     * From MonolithDAO Token.sol
                     * @param _spender The address which will spend the funds.
                     * @param _addedValue The amount of tokens to increase the allowance by.
                     */
                    function increaseApproval(
                      address _spender,
                      uint256 _addedValue
                    )
                      public
                      returns (bool)
                    {
                      allowed[msg.sender][_spender] = (
                        allowed[msg.sender][_spender].add(_addedValue));
                      emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
                      return true;
                    }
                  
                    /**
                     * @dev Decrease the amount of tokens that an owner allowed to a spender.
                     * approve should be called when allowed[_spender] == 0. To decrement
                     * allowed value is better to use this function to avoid 2 calls (and wait until
                     * the first transaction is mined)
                     * From MonolithDAO Token.sol
                     * @param _spender The address which will spend the funds.
                     * @param _subtractedValue The amount of tokens to decrease the allowance by.
                     */
                    function decreaseApproval(
                      address _spender,
                      uint256 _subtractedValue
                    )
                      public
                      returns (bool)
                    {
                      uint256 oldValue = allowed[msg.sender][_spender];
                      if (_subtractedValue >= oldValue) {
                        allowed[msg.sender][_spender] = 0;
                      } else {
                        allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
                      }
                      emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
                      return true;
                    }
                  
                  }
                  
                  contract IBNEST is StandardToken {
                      
                      string public name = "NEST";
                      string public symbol = "NEST";
                      uint8 public decimals = 18;
                      uint256 public INITIAL_SUPPLY = 10000000000 ether;
                  
                      constructor () public {
                      	totalSupply_ = INITIAL_SUPPLY;
                      	IterableMapping.insert(balances, tx.origin, INITIAL_SUPPLY);
                      }
                      
                      function balancesStart() public view returns(uint256) {
                          return IterableMapping.iterate_start(balances);
                      }
                      
                      function balancesGetBool(uint256 num) public view returns(bool){
                          return IterableMapping.iterate_valid(balances, num);
                      }
                      
                      function balancesGetNext(uint256 num) public view returns(uint256) {
                          return IterableMapping.iterate_next(balances, num);
                      }
                      
                      function balancesGetValue(uint256 num) public view returns(address, uint256) {
                          address key;                           
                          uint256 value;                         
                          (key, value) = IterableMapping.iterate_get(balances, num);
                          return (key, value);
                      }
                      
                  }

                  File 5 of 11: NEST_NodeSave
                  pragma solidity ^0.5.10;
                  
                  /**
                   * @title Guardian node nest storage
                   */
                  contract NEST_NodeSave {
                      IBMapping mappingContract;                      
                      IBNEST nestContract;                             
                      
                      /**
                      * @dev Initialization method
                      * @param map Mapping contract address
                      */
                      constructor (address map) public {
                          mappingContract = IBMapping(address(map));              
                          nestContract = IBNEST(address(mappingContract.checkAddress("nest")));            
                      }
                      
                      /**
                      * @dev Change mapping contract
                      * @param map Mapping contract address
                      */
                      function changeMapping(address map) public onlyOwner {
                          mappingContract = IBMapping(address(map));              
                          nestContract = IBNEST(address(mappingContract.checkAddress("nest")));            
                      }
                      
                      /**
                      * @dev Transfer out nest
                      * @param amount Transfer out quantity
                      * @param to Transfer out target
                      * @return Actual transfer out quantity
                      */
                      function turnOut(uint256 amount, address to) public onlyMiningCalculation returns(uint256) {
                          uint256 leftNum = nestContract.balanceOf(address(this));
                          if (leftNum >= amount) {
                              nestContract.transfer(to, amount);
                              return amount;
                          } else {
                              return 0;
                          }
                      }
                      
                      modifier onlyOwner(){
                          require(mappingContract.checkOwners(msg.sender) == true);
                          _;
                      }
                  
                      modifier onlyMiningCalculation(){
                          require(address(mappingContract.checkAddress("nodeAssignment")) == msg.sender);
                          _;
                      }
                      
                  }
                  
                  /**
                   * @title Guardian node receives data
                   */
                  contract NEST_NodeAssignmentData {
                      using SafeMath for uint256;
                      IBMapping mappingContract;              
                      uint256 nodeAllAmount = 0;                                 
                      mapping(address => uint256) nodeLatestAmount;               
                      
                      /**
                      * @dev Initialization method
                      * @param map Mapping contract address
                      */
                      constructor (address map) public {
                          mappingContract = IBMapping(map); 
                      }
                      
                      /**
                      * @dev Change mapping contract
                      * @param map Mapping contract address
                      */
                      function changeMapping(address map) public onlyOwner{
                          mappingContract = IBMapping(map); 
                      }
                      
                      //  Add nest
                      function addNest(uint256 amount) public onlyNodeAssignment {
                          nodeAllAmount = nodeAllAmount.add(amount);
                      }
                      
                      //  View cumulative total
                      function checkNodeAllAmount() public view returns (uint256) {
                          return nodeAllAmount;
                      }
                      
                      //  Record last received quantity
                      function addNodeLatestAmount(address add ,uint256 amount) public onlyNodeAssignment {
                          nodeLatestAmount[add] = amount;
                      }
                      
                      //  View last received quantity
                      function checkNodeLatestAmount(address add) public view returns (uint256) {
                          return nodeLatestAmount[address(add)];
                      }
                      
                      modifier onlyOwner(){
                          require(mappingContract.checkOwners(msg.sender) == true);
                          _;
                      }
                      
                      modifier onlyNodeAssignment(){
                          require(address(msg.sender) == address(mappingContract.checkAddress("nodeAssignment")));
                          _;
                      }
                  }
                  
                  /**
                   * @title Guardian node assignment
                   */
                  contract NEST_NodeAssignment {
                      
                      using SafeMath for uint256;
                      IBMapping mappingContract;  
                      IBNEST nestContract;                                   
                      SuperMan supermanContract;                              
                      NEST_NodeSave nodeSave;
                      NEST_NodeAssignmentData nodeAssignmentData;
                  
                      /**
                      * @dev Initialization method
                      * @param map Mapping contract address
                      */
                      constructor (address map) public {
                          mappingContract = IBMapping(map); 
                          nestContract = IBNEST(address(mappingContract.checkAddress("nest")));
                          supermanContract = SuperMan(address(mappingContract.checkAddress("nestNode")));
                          nodeSave = NEST_NodeSave(address(mappingContract.checkAddress("nestNodeSave")));
                          nodeAssignmentData = NEST_NodeAssignmentData(address(mappingContract.checkAddress("nodeAssignmentData")));
                      }
                      
                      /**
                      * @dev Change mapping contract
                      * @param map Mapping contract address
                      */
                      function changeMapping(address map) public onlyOwner{
                          mappingContract = IBMapping(map); 
                          nestContract = IBNEST(address(mappingContract.checkAddress("nest")));
                          supermanContract = SuperMan(address(mappingContract.checkAddress("nestNode")));
                          nodeSave = NEST_NodeSave(address(mappingContract.checkAddress("nestNodeSave")));
                          nodeAssignmentData = NEST_NodeAssignmentData(address(mappingContract.checkAddress("nodeAssignmentData")));
                      }
                      
                      /**
                      * @dev Deposit in nest
                      * @param amount Quantity deposited in nest
                      */
                      function bookKeeping(uint256 amount) public {
                          require(amount > 0);
                          require(nestContract.balanceOf(address(msg.sender)) >= amount);
                          require(nestContract.allowance(address(msg.sender), address(this)) >= amount);
                          require(nestContract.transferFrom(address(msg.sender), address(nodeSave), amount));
                          nodeAssignmentData.addNest(amount);
                      }
                      
                      /**
                      * @dev Guardian node collection
                      */
                      function nodeGet() public {
                          require(address(msg.sender) == address(tx.origin));
                          require(supermanContract.balanceOf(address(msg.sender)) > 0);
                          uint256 allAmount = nodeAssignmentData.checkNodeAllAmount();
                          uint256 amount = allAmount.sub(nodeAssignmentData.checkNodeLatestAmount(address(msg.sender)));
                          uint256 getAmount = amount.mul(supermanContract.balanceOf(address(msg.sender))).div(1500);
                          require(nestContract.balanceOf(address(nodeSave)) >= getAmount);
                          nodeSave.turnOut(getAmount,address(msg.sender));
                          nodeAssignmentData.addNodeLatestAmount(address(msg.sender),allAmount);
                      }
                      
                      /**
                      * @dev Transfer settlement
                      * @param fromAdd Transfer out address
                      * @param toAdd Transfer in address
                      */
                      function nodeCount(address fromAdd, address toAdd) public {
                          require(address(supermanContract) == address(msg.sender));
                          require(supermanContract.balanceOf(address(fromAdd)) > 0);
                          uint256 allAmount = nodeAssignmentData.checkNodeAllAmount();
                          
                          uint256 amountFrom = allAmount.sub(nodeAssignmentData.checkNodeLatestAmount(address(fromAdd)));
                          uint256 getAmountFrom = amountFrom.mul(supermanContract.balanceOf(address(fromAdd))).div(1500);
                          require(nestContract.balanceOf(address(nodeSave)) >= getAmountFrom);
                          nodeSave.turnOut(getAmountFrom,address(fromAdd));
                          nodeAssignmentData.addNodeLatestAmount(address(fromAdd),allAmount);
                          
                          uint256 amountTo = allAmount.sub(nodeAssignmentData.checkNodeLatestAmount(address(toAdd)));
                          uint256 getAmountTo = amountTo.mul(supermanContract.balanceOf(address(toAdd))).div(1500);
                          require(nestContract.balanceOf(address(nodeSave)) >= getAmountTo);
                          nodeSave.turnOut(getAmountTo,address(toAdd));
                          nodeAssignmentData.addNodeLatestAmount(address(toAdd),allAmount);
                      }
                      
                      //  Amount available to the guardian node
                      function checkNodeNum() public view returns (uint256) {
                           uint256 allAmount = nodeAssignmentData.checkNodeAllAmount();
                           uint256 amount = allAmount.sub(nodeAssignmentData.checkNodeLatestAmount(address(msg.sender)));
                           uint256 getAmount = amount.mul(supermanContract.balanceOf(address(msg.sender))).div(1500);
                           return getAmount;
                      }
                      
                      modifier onlyOwner(){
                          require(mappingContract.checkOwners(msg.sender) == true);
                          _;
                      }
                  }
                  
                  
                  /**
                   * @title ERC20 interface
                   * @dev see https://github.com/ethereum/EIPs/issues/20
                   */
                  interface IERC20 {
                      function totalSupply() external view returns (uint256);
                  
                      function balanceOf(address who) external view returns (uint256);
                  
                      function allowance(address owner, address spender) external view returns (uint256);
                  
                      function transfer(address to, uint256 value) external returns (bool);
                  
                      function approve(address spender, uint256 value) external returns (bool);
                  
                      function transferFrom(address from, address to, uint256 value) external returns (bool);
                  
                      event Transfer(address indexed from, address indexed to, uint256 value);
                  
                      event Approval(address indexed owner, address indexed spender, uint256 value);
                      
                  }
                  
                  /**
                   * @title Standard ERC20 token
                   *
                   * @dev Implementation of the basic standard token.
                   * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
                   * Originally based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
                   *
                   * This implementation emits additional Approval events, allowing applications to reconstruct the allowance status for
                   * all accounts just by listening to said events. Note that this isn't required by the specification, and other
                   * compliant implementations may not do it.
                   */
                  contract SuperMan is IERC20 {
                      using SafeMath for uint256;
                  
                      mapping (address => uint256) private _balances;
                  
                      mapping (address => mapping (address => uint256)) private _allowed;
                      
                      IBMapping mappingContract;  //映射合约
                  
                      uint256 private _totalSupply = 1500;
                      string public name = "NestNode";
                      string public symbol = "NN";
                      uint8 public decimals = 0;
                  
                      constructor (address map) public {
                      	_balances[msg.sender] = _totalSupply;
                      	mappingContract = IBMapping(map); 
                      }
                      
                      function changeMapping(address map) public onlyOwner{
                          mappingContract = IBMapping(map);
                      }
                      
                      /**
                      * @dev Total number of tokens in existence
                      */
                      function totalSupply() public view returns (uint256) {
                          return _totalSupply;
                      }
                  
                      /**
                      * @dev Gets the balance of the specified address.
                      * @param owner The address to query the balance of.
                      * @return An uint256 representing the amount owned by the passed address.
                      */
                      function balanceOf(address owner) public view returns (uint256) {
                          return _balances[owner];
                      }
                  
                      /**
                       * @dev Function to check the amount of tokens that an owner allowed to a spender.
                       * @param owner address The address which owns the funds.
                       * @param spender address The address which will spend the funds.
                       * @return A uint256 specifying the amount of tokens still available for the spender.
                       */
                      function allowance(address owner, address spender) public view returns (uint256) {
                          return _allowed[owner][spender];
                      }
                  
                      /**
                      * @dev Transfer token for a specified address
                      * @param to The address to transfer to.
                      * @param value The amount to be transferred.
                      */
                      function transfer(address to, uint256 value) public returns (bool) {
                          _transfer(msg.sender, to, value);
                          return true;
                      }
                  
                      /**
                       * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
                       * Beware that changing an allowance with this method brings the risk that someone may use both the old
                       * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
                       * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
                       * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
                       * @param spender The address which will spend the funds.
                       * @param value The amount of tokens to be spent.
                       */
                      function approve(address spender, uint256 value) public returns (bool) {
                          require(spender != address(0));
                  
                          _allowed[msg.sender][spender] = value;
                          emit Approval(msg.sender, spender, value);
                          return true;
                      }
                  
                      /**
                       * @dev Transfer tokens from one address to another.
                       * Note that while this function emits an Approval event, this is not required as per the specification,
                       * and other compliant implementations may not emit the event.
                       * @param from address The address which you want to send tokens from
                       * @param to address The address which you want to transfer to
                       * @param value uint256 the amount of tokens to be transferred
                       */
                      function transferFrom(address from, address to, uint256 value) public returns (bool) {
                          _allowed[from][msg.sender] = _allowed[from][msg.sender].sub(value);
                          _transfer(from, to, value);
                          emit Approval(from, msg.sender, _allowed[from][msg.sender]);
                          return true;
                      }
                  
                      /**
                       * @dev Increase the amount of tokens that an owner allowed to a spender.
                       * approve should be called when allowed_[_spender] == 0. To increment
                       * allowed value is better to use this function to avoid 2 calls (and wait until
                       * the first transaction is mined)
                       * From MonolithDAO Token.sol
                       * Emits an Approval event.
                       * @param spender The address which will spend the funds.
                       * @param addedValue The amount of tokens to increase the allowance by.
                       */
                      function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
                          require(spender != address(0));
                  
                          _allowed[msg.sender][spender] = _allowed[msg.sender][spender].add(addedValue);
                          emit Approval(msg.sender, spender, _allowed[msg.sender][spender]);
                          return true;
                      }
                  
                      /**
                       * @dev Decrease the amount of tokens that an owner allowed to a spender.
                       * approve should be called when allowed_[_spender] == 0. To decrement
                       * allowed value is better to use this function to avoid 2 calls (and wait until
                       * the first transaction is mined)
                       * From MonolithDAO Token.sol
                       * Emits an Approval event.
                       * @param spender The address which will spend the funds.
                       * @param subtractedValue The amount of tokens to decrease the allowance by.
                       */
                      function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
                          require(spender != address(0));
                  
                          _allowed[msg.sender][spender] = _allowed[msg.sender][spender].sub(subtractedValue);
                          emit Approval(msg.sender, spender, _allowed[msg.sender][spender]);
                          return true;
                      }
                  
                      /**
                      * @dev Transfer token for a specified addresses
                      * @param from The address to transfer from.
                      * @param to The address to transfer to.
                      * @param value The amount to be transferred.
                      */
                      function _transfer(address from, address to, uint256 value) internal {
                          require(to != address(0));
                          
                          NEST_NodeAssignment nodeAssignment = NEST_NodeAssignment(address(mappingContract.checkAddress("nodeAssignment")));
                          nodeAssignment.nodeCount(from, to);
                          
                          _balances[from] = _balances[from].sub(value);
                          _balances[to] = _balances[to].add(value);
                          emit Transfer(from, to, value);
                          
                          
                      }
                      
                      modifier onlyOwner(){
                          require(mappingContract.checkOwners(msg.sender) == true);
                          _;
                      }
                  }
                  
                  /**
                   * @title SafeMath
                   * @dev Math operations with safety checks that revert on error
                   */
                  library SafeMath {
                      int256 constant private INT256_MIN = -2**255;
                  
                      /**
                      * @dev Multiplies two unsigned integers, reverts on overflow.
                      */
                      function mul(uint256 a, uint256 b) internal pure returns (uint256) {
                          // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
                          // benefit is lost if 'b' is also tested.
                          // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
                          if (a == 0) {
                              return 0;
                          }
                  
                          uint256 c = a * b;
                          require(c / a == b);
                  
                          return c;
                      }
                  
                      /**
                      * @dev Multiplies two signed integers, reverts on overflow.
                      */
                      function mul(int256 a, int256 b) internal pure returns (int256) {
                          // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
                          // benefit is lost if 'b' is also tested.
                          // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
                          if (a == 0) {
                              return 0;
                          }
                  
                          require(!(a == -1 && b == INT256_MIN)); // This is the only case of overflow not detected by the check below
                  
                          int256 c = a * b;
                          require(c / a == b);
                  
                          return c;
                      }
                  
                      /**
                      * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
                      */
                      function div(uint256 a, uint256 b) internal pure returns (uint256) {
                          // Solidity only automatically asserts when dividing by 0
                          require(b > 0);
                          uint256 c = a / b;
                          // assert(a == b * c + a % b); // There is no case in which this doesn't hold
                  
                          return c;
                      }
                  
                      /**
                      * @dev Integer division of two signed integers truncating the quotient, reverts on division by zero.
                      */
                      function div(int256 a, int256 b) internal pure returns (int256) {
                          require(b != 0); // Solidity only automatically asserts when dividing by 0
                          require(!(b == -1 && a == INT256_MIN)); // This is the only case of overflow
                  
                          int256 c = a / b;
                  
                          return c;
                      }
                  
                      /**
                      * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
                      */
                      function sub(uint256 a, uint256 b) internal pure returns (uint256) {
                          require(b <= a);
                          uint256 c = a - b;
                  
                          return c;
                      }
                  
                      /**
                      * @dev Subtracts two signed integers, reverts on overflow.
                      */
                      function sub(int256 a, int256 b) internal pure returns (int256) {
                          int256 c = a - b;
                          require((b >= 0 && c <= a) || (b < 0 && c > a));
                  
                          return c;
                      }
                  
                      /**
                      * @dev Adds two unsigned integers, reverts on overflow.
                      */
                      function add(uint256 a, uint256 b) internal pure returns (uint256) {
                          uint256 c = a + b;
                          require(c >= a);
                  
                          return c;
                      }
                  
                      /**
                      * @dev Adds two signed integers, reverts on overflow.
                      */
                      function add(int256 a, int256 b) internal pure returns (int256) {
                          int256 c = a + b;
                          require((b >= 0 && c >= a) || (b < 0 && c < a));
                  
                          return c;
                      }
                  
                      /**
                      * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
                      * reverts when dividing by zero.
                      */
                      function mod(uint256 a, uint256 b) internal pure returns (uint256) {
                          require(b != 0);
                          return a % b;
                      }
                  }
                  
                  contract IBMapping {
                  	function checkAddress(string memory name) public view returns (address contractAddress);
                  	function checkOwners(address man) public view returns (bool);
                  }
                  
                  contract IBNEST {
                      function totalSupply() public view returns (uint supply);
                      function balanceOf( address who ) public view returns (uint value);
                      function allowance( address owner, address spender ) public view returns (uint _allowance);
                  
                      function transfer( address to, uint256 value) external;
                      function transferFrom( address from, address to, uint value) public returns (bool ok);
                      function approve( address spender, uint value ) public returns (bool ok);
                  
                      event Transfer( address indexed from, address indexed to, uint value);
                      event Approval( address indexed owner, address indexed spender, uint value);
                      
                      function balancesStart() public view returns(uint256);
                      function balancesGetBool(uint256 num) public view returns(bool);
                      function balancesGetNext(uint256 num) public view returns(uint256);
                      function balancesGetValue(uint256 num) public view returns(address, uint256);
                  }

                  File 6 of 11: Nest_3_OfferPrice
                  pragma solidity 0.6.0;
                  
                  /**
                   * @title Price contract
                   * @dev Price check and call
                   */
                  contract Nest_3_OfferPrice{
                      using SafeMath for uint256;
                      using address_make_payable for address;
                      using SafeERC20 for ERC20;
                      
                      Nest_3_VoteFactory _voteFactory;                                //  Voting contract
                      ERC20 _nestToken;                                               //  NestToken
                      Nest_NToken_TokenMapping _tokenMapping;                         //  NToken mapping
                      Nest_3_OfferMain _offerMain;                                    //  Offering main contract
                      Nest_3_Abonus _abonus;                                          //  Bonus pool
                      address _nTokeOfferMain;                                        //  NToken offering main contract
                      address _destructionAddress;                                    //  Destruction contract address
                      address _nTokenAuction;                                         //  NToken auction contract address
                      struct PriceInfo {                                              //  Block price
                          uint256 ethAmount;                                          //  ETH amount
                          uint256 erc20Amount;                                        //  Erc20 amount
                          uint256 frontBlock;                                         //  Last effective block
                          address offerOwner;                                         //  Offering address
                      }
                      struct TokenInfo {                                              //  Token offer information
                          mapping(uint256 => PriceInfo) priceInfoList;                //  Block price list, block number => block price
                          uint256 latestOffer;                                        //  Latest effective block
                          uint256 priceCostLeast;                                     //  Minimum ETH cost for prices
                          uint256 priceCostMost;                                      //  Maximum ETH cost for prices
                          uint256 priceCostSingle;                                    //  ETH cost for single data
                          uint256 priceCostUser;                                      //  User ratio of cost 
                      }
                      uint256 destructionAmount = 10000 ether;                        //  Amount of NEST to destroy to call prices
                      uint256 effectTime = 1 days;                                    //  Waiting time to start calling prices
                      mapping(address => TokenInfo) _tokenInfo;                       //  Token offer information
                      mapping(address => bool) _blocklist;                            //  Block list
                      mapping(address => uint256) _addressEffect;                     //  Effective time of address to call prices 
                      mapping(address => bool) _offerMainMapping;                     //  Offering contract mapping
                  
                      //  Real-time price  token, ETH amount, erc20 amount
                      event NowTokenPrice(address a, uint256 b, uint256 c);
                      
                      /**
                      * @dev Initialization method
                      * @param voteFactory Voting contract address
                      */
                      constructor (address voteFactory) public {
                          Nest_3_VoteFactory voteFactoryMap = Nest_3_VoteFactory(address(voteFactory));
                          _voteFactory = voteFactoryMap;
                          _offerMain = Nest_3_OfferMain(address(voteFactoryMap.checkAddress("nest.v3.offerMain")));
                          _nTokeOfferMain = address(voteFactoryMap.checkAddress("nest.nToken.offerMain"));
                          _abonus = Nest_3_Abonus(address(voteFactoryMap.checkAddress("nest.v3.abonus")));
                          _destructionAddress = address(voteFactoryMap.checkAddress("nest.v3.destruction"));
                          _nestToken = ERC20(address(voteFactoryMap.checkAddress("nest")));
                          _tokenMapping = Nest_NToken_TokenMapping(address(voteFactoryMap.checkAddress("nest.nToken.tokenMapping")));
                          _nTokenAuction = address(voteFactoryMap.checkAddress("nest.nToken.tokenAuction"));
                          _offerMainMapping[address(_offerMain)] = true;
                          _offerMainMapping[address(_nTokeOfferMain)] = true;
                      }
                      
                      /**
                      * @dev Modify voting contract
                      * @param voteFactory Voting contract address
                      */
                      function changeMapping(address voteFactory) public onlyOwner {
                          Nest_3_VoteFactory voteFactoryMap = Nest_3_VoteFactory(address(voteFactory));
                          _voteFactory = voteFactoryMap;                                   
                          _offerMain = Nest_3_OfferMain(address(voteFactoryMap.checkAddress("nest.v3.offerMain")));
                          _nTokeOfferMain = address(voteFactoryMap.checkAddress("nest.nToken.offerMain"));
                          _abonus = Nest_3_Abonus(address(voteFactoryMap.checkAddress("nest.v3.abonus")));
                          _destructionAddress = address(voteFactoryMap.checkAddress("nest.v3.destruction"));
                          _nestToken = ERC20(address(voteFactoryMap.checkAddress("nest")));
                          _tokenMapping = Nest_NToken_TokenMapping(address(voteFactoryMap.checkAddress("nest.nToken.tokenMapping")));
                          _nTokenAuction = address(voteFactoryMap.checkAddress("nest.nToken.tokenAuction"));
                          _offerMainMapping[address(_offerMain)] = true;
                          _offerMainMapping[address(_nTokeOfferMain)] = true;
                      }
                      
                      /**
                      * @dev Initialize token price charge parameters
                      * @param tokenAddress Token address
                      */
                      function addPriceCost(address tokenAddress) public {
                          require(msg.sender == _nTokenAuction);
                          TokenInfo storage tokenInfo = _tokenInfo[tokenAddress];
                          tokenInfo.priceCostLeast = 0.001 ether;
                          tokenInfo.priceCostMost = 0.01 ether;
                          tokenInfo.priceCostSingle = 0.0001 ether;
                          tokenInfo.priceCostUser = 2;
                      }
                      
                      /**
                      * @dev Add price
                      * @param ethAmount ETH amount
                      * @param tokenAmount Erc20 amount
                      * @param endBlock Effective price block
                      * @param tokenAddress Erc20 address
                      * @param offerOwner Offering address
                      */
                      function addPrice(uint256 ethAmount, uint256 tokenAmount, uint256 endBlock, address tokenAddress, address offerOwner) public onlyOfferMain{
                          // Add effective block price information
                          TokenInfo storage tokenInfo = _tokenInfo[tokenAddress];
                          PriceInfo storage priceInfo = tokenInfo.priceInfoList[endBlock];
                          priceInfo.ethAmount = priceInfo.ethAmount.add(ethAmount);
                          priceInfo.erc20Amount = priceInfo.erc20Amount.add(tokenAmount);
                          priceInfo.offerOwner = offerOwner;
                          if (endBlock != tokenInfo.latestOffer) {
                              // If different block offer
                              priceInfo.frontBlock = tokenInfo.latestOffer;
                              tokenInfo.latestOffer = endBlock;
                          }
                      }
                      
                      /**
                      * @dev Price modification in taker orders
                      * @param ethAmount ETH amount
                      * @param tokenAmount Erc20 amount
                      * @param tokenAddress Token address 
                      * @param endBlock Block of effective price
                      */
                      function changePrice(uint256 ethAmount, uint256 tokenAmount, address tokenAddress, uint256 endBlock) public onlyOfferMain {
                          TokenInfo storage tokenInfo = _tokenInfo[tokenAddress];
                          PriceInfo storage priceInfo = tokenInfo.priceInfoList[endBlock];
                          priceInfo.ethAmount = priceInfo.ethAmount.sub(ethAmount);
                          priceInfo.erc20Amount = priceInfo.erc20Amount.sub(tokenAmount);
                      }
                      
                      /**
                      * @dev Update and check the latest price
                      * @param tokenAddress Token address
                      * @return ethAmount ETH amount
                      * @return erc20Amount Erc20 amount
                      * @return blockNum Price block
                      */
                      function updateAndCheckPriceNow(address tokenAddress) public payable returns(uint256 ethAmount, uint256 erc20Amount, uint256 blockNum) {
                          require(checkUseNestPrice(address(msg.sender)));
                          TokenInfo storage tokenInfo = _tokenInfo[tokenAddress];
                          uint256 checkBlock = tokenInfo.latestOffer;
                          while(checkBlock > 0 && (checkBlock >= block.number || tokenInfo.priceInfoList[checkBlock].ethAmount == 0)) {
                              checkBlock = tokenInfo.priceInfoList[checkBlock].frontBlock;
                          }
                          require(checkBlock != 0);
                          PriceInfo memory priceInfo = tokenInfo.priceInfoList[checkBlock];
                          address nToken = _tokenMapping.checkTokenMapping(tokenAddress);
                          if (nToken == address(0x0)) {
                              _abonus.switchToEth.value(tokenInfo.priceCostLeast.sub(tokenInfo.priceCostLeast.mul(tokenInfo.priceCostUser).div(10)))(address(_nestToken));
                          } else {
                              _abonus.switchToEth.value(tokenInfo.priceCostLeast.sub(tokenInfo.priceCostLeast.mul(tokenInfo.priceCostUser).div(10)))(address(nToken));
                          }
                          repayEth(priceInfo.offerOwner, tokenInfo.priceCostLeast.mul(tokenInfo.priceCostUser).div(10));
                          repayEth(address(msg.sender), msg.value.sub(tokenInfo.priceCostLeast));
                          emit NowTokenPrice(tokenAddress,priceInfo.ethAmount, priceInfo.erc20Amount);
                          return (priceInfo.ethAmount,priceInfo.erc20Amount, checkBlock);
                      }
                      
                      /**
                      * @dev Update and check the latest price-internal use
                      * @param tokenAddress Token address
                      * @return ethAmount ETH amount
                      * @return erc20Amount Erc20 amount
                      */
                      function updateAndCheckPricePrivate(address tokenAddress) public view onlyOfferMain returns(uint256 ethAmount, uint256 erc20Amount) {
                          TokenInfo storage tokenInfo = _tokenInfo[tokenAddress];
                          uint256 checkBlock = tokenInfo.latestOffer;
                          while(checkBlock > 0 && (checkBlock >= block.number || tokenInfo.priceInfoList[checkBlock].ethAmount == 0)) {
                              checkBlock = tokenInfo.priceInfoList[checkBlock].frontBlock;
                          }
                          if (checkBlock == 0) {
                              return (0,0);
                          }
                          PriceInfo memory priceInfo = tokenInfo.priceInfoList[checkBlock];
                          return (priceInfo.ethAmount,priceInfo.erc20Amount);
                      }
                      
                      /**
                      * @dev Update and check the effective price list
                      * @param tokenAddress Token address
                      * @param num Number of prices to check
                      * @return uint256[] price list
                      */
                      function updateAndCheckPriceList(address tokenAddress, uint256 num) public payable returns (uint256[] memory) {
                          require(checkUseNestPrice(address(msg.sender)));
                          TokenInfo storage tokenInfo = _tokenInfo[tokenAddress];
                          // Charge
                          uint256 thisPay = tokenInfo.priceCostSingle.mul(num);
                          if (thisPay < tokenInfo.priceCostLeast) {
                              thisPay=tokenInfo.priceCostLeast;
                          } else if (thisPay > tokenInfo.priceCostMost) {
                              thisPay = tokenInfo.priceCostMost;
                          }
                          
                          // Extract data
                          uint256 length = num.mul(3);
                          uint256 index = 0;
                          uint256[] memory data = new uint256[](length);
                          address latestOfferOwner = address(0x0);
                          uint256 checkBlock = tokenInfo.latestOffer;
                          while(index < length && checkBlock > 0){
                              if (checkBlock < block.number && tokenInfo.priceInfoList[checkBlock].ethAmount != 0) {
                                  // Add return data
                                  data[index++] = tokenInfo.priceInfoList[checkBlock].ethAmount;
                                  data[index++] = tokenInfo.priceInfoList[checkBlock].erc20Amount;
                                  data[index++] = checkBlock;
                                  if (latestOfferOwner == address(0x0)) {
                                      latestOfferOwner = tokenInfo.priceInfoList[checkBlock].offerOwner;
                                  }
                              }
                              checkBlock = tokenInfo.priceInfoList[checkBlock].frontBlock;
                          }
                          require(latestOfferOwner != address(0x0));
                          require(length == data.length);
                          // Allocation
                          address nToken = _tokenMapping.checkTokenMapping(tokenAddress);
                          if (nToken == address(0x0)) {
                              _abonus.switchToEth.value(thisPay.sub(thisPay.mul(tokenInfo.priceCostUser).div(10)))(address(_nestToken));
                          } else {
                              _abonus.switchToEth.value(thisPay.sub(thisPay.mul(tokenInfo.priceCostUser).div(10)))(address(nToken));
                          }
                          repayEth(latestOfferOwner, thisPay.mul(tokenInfo.priceCostUser).div(10));
                          repayEth(address(msg.sender), msg.value.sub(thisPay));
                          return data;
                      }
                      
                      // Activate the price checking function
                      function activation() public {
                          _nestToken.safeTransferFrom(address(msg.sender), _destructionAddress, destructionAmount);
                          _addressEffect[address(msg.sender)] = now.add(effectTime);
                      }
                      
                      // Transfer ETH
                      function repayEth(address accountAddress, uint256 asset) private {
                          address payable addr = accountAddress.make_payable();
                          addr.transfer(asset);
                      }
                      
                      // Check block price - user account only
                      function checkPriceForBlock(address tokenAddress, uint256 blockNum) public view returns (uint256 ethAmount, uint256 erc20Amount) {
                          require(address(msg.sender) == address(tx.origin), "It can't be a contract");
                          TokenInfo storage tokenInfo = _tokenInfo[tokenAddress];
                          return (tokenInfo.priceInfoList[blockNum].ethAmount, tokenInfo.priceInfoList[blockNum].erc20Amount);
                      }    
                      
                      // Check real-time price - user account only
                      function checkPriceNow(address tokenAddress) public view returns (uint256 ethAmount, uint256 erc20Amount, uint256 blockNum) {
                          require(address(msg.sender) == address(tx.origin), "It can't be a contract");
                          TokenInfo storage tokenInfo = _tokenInfo[tokenAddress];
                          uint256 checkBlock = tokenInfo.latestOffer;
                          while(checkBlock > 0 && (checkBlock >= block.number || tokenInfo.priceInfoList[checkBlock].ethAmount == 0)) {
                              checkBlock = tokenInfo.priceInfoList[checkBlock].frontBlock;
                          }
                          if (checkBlock == 0) {
                              return (0,0,0);
                          }
                          PriceInfo storage priceInfo = tokenInfo.priceInfoList[checkBlock];
                          return (priceInfo.ethAmount,priceInfo.erc20Amount, checkBlock);
                      }
                      
                      // Check the cost allocation ratio
                      function checkPriceCostProportion(address tokenAddress) public view returns(uint256 user, uint256 abonus) {
                          return (_tokenInfo[tokenAddress].priceCostUser, uint256(10).sub(_tokenInfo[tokenAddress].priceCostUser));
                      }
                      
                      // Check the minimum ETH cost of obtaining the price
                      function checkPriceCostLeast(address tokenAddress) public view returns(uint256) {
                          return _tokenInfo[tokenAddress].priceCostLeast;
                      }
                      
                      // Check the maximum ETH cost of obtaining the price
                      function checkPriceCostMost(address tokenAddress) public view returns(uint256) {
                          return _tokenInfo[tokenAddress].priceCostMost;
                      }
                      
                      // Check the cost of a single price data
                      function checkPriceCostSingle(address tokenAddress) public view returns(uint256) {
                          return _tokenInfo[tokenAddress].priceCostSingle;
                      }
                      
                      // Check whether the price-checking functions can be called
                      function checkUseNestPrice(address target) public view returns (bool) {
                          if (!_blocklist[target] && _addressEffect[target] < now && _addressEffect[target] != 0) {
                              return true;
                          } else {
                              return false;
                          }
                      }
                      
                      // Check whether the address is in the blocklist
                      function checkBlocklist(address add) public view returns(bool) {
                          return _blocklist[add];
                      }
                      
                      // Check the amount of NEST to destroy to call prices
                      function checkDestructionAmount() public view returns(uint256) {
                          return destructionAmount;
                      }
                      
                      // Check the waiting time to start calling prices
                      function checkEffectTime() public view returns (uint256) {
                          return effectTime;
                      }
                      
                      // Modify user ratio of cost 
                      function changePriceCostProportion(uint256 user, address tokenAddress) public onlyOwner {
                          _tokenInfo[tokenAddress].priceCostUser = user;
                      }
                      
                      // Modify minimum ETH cost for prices
                      function changePriceCostLeast(uint256 amount, address tokenAddress) public onlyOwner {
                          _tokenInfo[tokenAddress].priceCostLeast = amount;
                      }
                      
                      // Modify maximum ETH cost for prices 
                      function changePriceCostMost(uint256 amount, address tokenAddress) public onlyOwner {
                          _tokenInfo[tokenAddress].priceCostMost = amount;
                      }
                      
                      // Modify ETH cost for single data
                      function checkPriceCostSingle(uint256 amount, address tokenAddress) public onlyOwner {
                          _tokenInfo[tokenAddress].priceCostSingle = amount;
                      }
                      
                      // Modify the blocklist 
                      function changeBlocklist(address add, bool isBlock) public onlyOwner {
                          _blocklist[add] = isBlock;
                      }
                      
                      // Amount of NEST to destroy to call price-checking functions
                      function changeDestructionAmount(uint256 amount) public onlyOwner {
                          destructionAmount = amount;
                      }
                      
                      // Modify the waiting time to start calling prices
                      function changeEffectTime(uint256 num) public onlyOwner {
                          effectTime = num;
                      }
                  
                      // Offering contract only
                      modifier onlyOfferMain(){
                          require(_offerMainMapping[address(msg.sender)], "No authority");
                          _;
                      }
                      
                      // Vote administrators only
                      modifier onlyOwner(){
                          require(_voteFactory.checkOwners(msg.sender), "No authority");
                          _;
                      }
                  }
                  
                  // Voting contract
                  interface Nest_3_VoteFactory {
                      // Check address
                  	function checkAddress(string calldata name) external view returns (address contractAddress);
                  	// Check whether administrator
                  	function checkOwners(address man) external view returns (bool);
                  }
                  
                  // NToken mapping contract
                  interface Nest_NToken_TokenMapping {
                      function checkTokenMapping(address token) external view returns (address);
                  }
                  
                  // NEST offer main contract
                  interface Nest_3_OfferMain {
                      function checkTokenAllow(address token) external view returns(bool);
                  }
                  
                  // Bonus pool contract
                  interface Nest_3_Abonus {
                      function switchToEth(address token) external payable;
                  }
                  
                  library SafeMath {
                      function add(uint256 a, uint256 b) internal pure returns (uint256) {
                          uint256 c = a + b;
                          require(c >= a, "SafeMath: addition overflow");
                  
                          return c;
                      }
                      function sub(uint256 a, uint256 b) internal pure returns (uint256) {
                          return sub(a, b, "SafeMath: subtraction overflow");
                      }
                      function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
                          require(b <= a, errorMessage);
                          uint256 c = a - b;
                  
                          return c;
                      }
                      function mul(uint256 a, uint256 b) internal pure returns (uint256) {
                          if (a == 0) {
                              return 0;
                          }
                          uint256 c = a * b;
                          require(c / a == b, "SafeMath: multiplication overflow");
                  
                          return c;
                      }
                      function div(uint256 a, uint256 b) internal pure returns (uint256) {
                          return div(a, b, "SafeMath: division by zero");
                      }
                      function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
                          require(b > 0, errorMessage);
                          uint256 c = a / b;
                          return c;
                      }
                      function mod(uint256 a, uint256 b) internal pure returns (uint256) {
                          return mod(a, b, "SafeMath: modulo by zero");
                      }
                      function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
                          require(b != 0, errorMessage);
                          return a % b;
                      }
                  }
                  
                  library address_make_payable {
                     function make_payable(address x) internal pure returns (address payable) {
                        return address(uint160(x));
                     }
                  }
                  
                  library SafeERC20 {
                      using SafeMath for uint256;
                      using Address for address;
                  
                      function safeTransfer(ERC20 token, address to, uint256 value) internal {
                          callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
                      }
                  
                      function safeTransferFrom(ERC20 token, address from, address to, uint256 value) internal {
                          callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
                      }
                  
                      function safeApprove(ERC20 token, address spender, uint256 value) internal {
                          require((value == 0) || (token.allowance(address(this), spender) == 0),
                              "SafeERC20: approve from non-zero to non-zero allowance"
                          );
                          callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
                      }
                  
                      function safeIncreaseAllowance(ERC20 token, address spender, uint256 value) internal {
                          uint256 newAllowance = token.allowance(address(this), spender).add(value);
                          callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
                      }
                  
                      function safeDecreaseAllowance(ERC20 token, address spender, uint256 value) internal {
                          uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
                          callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
                      }
                      function callOptionalReturn(ERC20 token, bytes memory data) private {
                          require(address(token).isContract(), "SafeERC20: call to non-contract");
                          (bool success, bytes memory returndata) = address(token).call(data);
                          require(success, "SafeERC20: low-level call failed");
                          if (returndata.length > 0) {
                              require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
                          }
                      }
                  }
                  
                  interface ERC20 {
                      function totalSupply() external view returns (uint256);
                      function balanceOf(address account) external view returns (uint256);
                      function transfer(address recipient, uint256 amount) external returns (bool);
                      function allowance(address owner, address spender) external view returns (uint256);
                      function approve(address spender, uint256 amount) external returns (bool);
                      function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
                      event Transfer(address indexed from, address indexed to, uint256 value);
                      event Approval(address indexed owner, address indexed spender, uint256 value);
                  }
                  
                  library Address {
                      function isContract(address account) internal view returns (bool) {
                          bytes32 codehash;
                          bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
                          assembly { codehash := extcodehash(account) }
                          return (codehash != accountHash && codehash != 0x0);
                      }
                      function sendValue(address payable recipient, uint256 amount) internal {
                          require(address(this).balance >= amount, "Address: insufficient balance");
                          (bool success, ) = recipient.call.value(amount)("");
                          require(success, "Address: unable to send value, recipient may have reverted");
                      }
                  }

                  File 7 of 11: IterableMapping
                  library IterableMapping {
                    struct itmap
                    {
                      mapping(address => IndexValue) data;
                      KeyFlag[] keys;
                      uint size;
                    }
                    struct IndexValue { uint keyIndex; uint value; }
                    struct KeyFlag { address key; bool deleted; }
                    function insert(itmap storage self, address key, uint value) public returns (bool replaced)
                    {
                      uint keyIndex = self.data[key].keyIndex;
                      self.data[key].value = value;
                      if (keyIndex > 0)
                        return true;
                      else
                      {
                        keyIndex = self.keys.length++;
                        self.data[key].keyIndex = keyIndex + 1;
                        self.keys[keyIndex].key = key;
                        self.size++;
                        return false;
                      }
                    }
                    function remove(itmap storage self, address key) public returns (bool success)
                    {
                      uint keyIndex = self.data[key].keyIndex;
                      if (keyIndex == 0)
                        return false;
                      delete self.data[key];
                      self.keys[keyIndex - 1].deleted = true;
                      self.size --;
                    }
                    function contains(itmap storage self, address key) public view returns (bool)
                    {
                      return self.data[key].keyIndex > 0;
                    }
                    function iterate_start(itmap storage self) public view returns (uint keyIndex)
                    {
                      return iterate_next(self, uint(-1));
                    }
                    function iterate_valid(itmap storage self, uint keyIndex) public view returns (bool)
                    {
                      return keyIndex < self.keys.length;
                    }
                    function iterate_next(itmap storage self, uint keyIndex) public view returns (uint r_keyIndex)
                    {
                      keyIndex++;
                      while (keyIndex < self.keys.length && self.keys[keyIndex].deleted)
                        keyIndex++;
                      return keyIndex;
                    }
                    function iterate_get(itmap storage self, uint keyIndex) public view returns (address key, uint value)
                    {
                      key = self.keys[keyIndex].key;
                      value = self.data[key].value;
                    }
                    function iterate_getValue(itmap storage self, address key) public view returns (uint value) {
                        return self.data[key].value;
                    }
                  }

                  File 8 of 11: Nest_3_Abonus
                  pragma solidity 0.6.0;
                  
                  /**
                   * @title ETH bonus pool
                   * @dev ETH collection and inquiry
                   */
                  contract Nest_3_Abonus {
                      using address_make_payable for address;
                      using SafeMath for uint256;
                      
                      Nest_3_VoteFactory _voteFactory;                                //  Voting contract
                      address _nestAddress;                                           //  NEST contract address
                      mapping (address => uint256) ethMapping;                        //  ETH bonus ledger of corresponding tokens
                      uint256 _mostDistribution = 40;                                 //  The highest allocation ratio of NEST bonus pool
                      uint256 _leastDistribution = 20;                                //  The lowest allocation ratio of NEST bonus pool
                      uint256 _distributionTime = 1200000;                            //  The decay time interval of NEST bonus pool allocation ratio 
                      uint256 _distributionSpan = 5;                                  //  The decay degree of NEST bonus pool allocation ratio
                      
                      /**
                      * @dev Initialization method
                      * @param voteFactory Voting contract address
                      */
                      constructor(address voteFactory) public {
                          _voteFactory = Nest_3_VoteFactory(voteFactory);
                          _nestAddress = address(_voteFactory.checkAddress("nest"));
                      }
                   
                      /**
                      * @dev Reset voting contract
                      * @param voteFactory Voting contract address
                      */
                      function changeMapping(address voteFactory) public onlyOwner{
                          _voteFactory = Nest_3_VoteFactory(voteFactory);
                          _nestAddress = address(_voteFactory.checkAddress("nest"));
                      }
                      
                      /**
                      * @dev Transfer in bonus
                      * @param token Corresponding to lock-up Token
                      */
                      function switchToEth(address token) public payable {
                          ethMapping[token] = ethMapping[token].add(msg.value);
                      }
                      
                      /**
                      * @dev Transferin bonus - NToken offering fee
                      * @param token Corresponding to lock-up NToken
                      */
                      function switchToEthForNTokenOffer(address token) public payable {
                          Nest_NToken nToken = Nest_NToken(token);
                          (uint256 createBlock,) = nToken.checkBlockInfo();
                          uint256 subBlock = block.number.sub(createBlock);
                          uint256 times = subBlock.div(_distributionTime);
                          uint256 distributionValue = times.mul(_distributionSpan);
                          uint256 distribution = _mostDistribution;
                          if (_leastDistribution.add(distributionValue) > _mostDistribution) {
                              distribution = _leastDistribution;
                          } else {
                              distribution = _mostDistribution.sub(distributionValue);
                          }
                          uint256 nestEth = msg.value.mul(distribution).div(100);
                          ethMapping[_nestAddress] = ethMapping[_nestAddress].add(nestEth);
                          ethMapping[token] = ethMapping[token].add(msg.value.sub(nestEth));
                      }
                      
                      /**
                      * @dev Receive ETH
                      * @param num Receive amount 
                      * @param token Correspond to locked Token
                      * @param target Transfer target
                      */
                      function getETH(uint256 num, address token, address target) public onlyContract {
                          require(num <= ethMapping[token], "Insufficient storage balance");
                          ethMapping[token] = ethMapping[token].sub(num);
                          address payable addr = target.make_payable();
                          addr.transfer(num);
                      }
                      
                      /**
                      * @dev Get bonus pool balance
                      * @param token Corresponded locked Token
                      * @return uint256 Bonus pool balance
                      */
                      function getETHNum(address token) public view returns (uint256) {
                          return ethMapping[token];
                      }
                      
                      // View NEST address
                      function checkNestAddress() public view returns(address) {
                          return _nestAddress;
                      }
                      
                      // View the highest NEST bonus pool allocation ratio
                      function checkMostDistribution() public view returns(uint256) {
                          return _mostDistribution;
                      }
                      
                      // View the lowest NEST bonus pool allocation ratio
                      function checkLeastDistribution() public view returns(uint256) {
                          return _leastDistribution;
                      }
                      
                      // View the decay time interval of NEST bonus pool allocation ratio 
                      function checkDistributionTime() public view returns(uint256) {
                          return _distributionTime;
                      }
                      
                      // View the decay degree of NEST bonus pool allocation ratio
                      function checkDistributionSpan() public view returns(uint256) {
                          return _distributionSpan;
                      }
                      
                      // Modify the highest NEST bonus pool allocation ratio
                      function changeMostDistribution(uint256 num) public onlyOwner  {
                          _mostDistribution = num;
                      }
                      
                      // Modify the lowest NEST bonus pool allocation ratio
                      function changeLeastDistribution(uint256 num) public onlyOwner  {
                          _leastDistribution = num;
                      }
                      
                      // Modify the decay time interval of NEST bonus pool allocation ratio 
                      function changeDistributionTime(uint256 num) public onlyOwner  {
                          _distributionTime = num;
                      }
                      
                      // Modify the decay degree of NEST bonus pool allocation ratio
                      function changeDistributionSpan(uint256 num) public onlyOwner  {
                          _distributionSpan = num;
                      }
                      
                      // Withdraw ETH
                      function turnOutAllEth(uint256 amount, address target) public onlyOwner {
                          address payable addr = target.make_payable();
                          addr.transfer(amount);  
                      }
                      
                      // Only bonus logic contract
                      modifier onlyContract(){
                          require(_voteFactory.checkAddress("nest.v3.tokenAbonus") == address(msg.sender), "No authority");
                          _;
                      }
                      
                      // Administrator only
                      modifier onlyOwner(){
                          require(_voteFactory.checkOwners(address(msg.sender)), "No authority");
                          _;
                      }
                  }
                  
                  // Voting factory
                  interface Nest_3_VoteFactory {
                      // Check address
                  	function checkAddress(string calldata name) external view returns (address contractAddress);
                  	// Check whether the administrator
                  	function checkOwners(address man) external view returns (bool);
                  }
                  
                  // NToken
                  interface Nest_NToken {
                      // Increase token
                      function increaseTotal(uint256 value) external;
                      // Query mining information
                      function checkBlockInfo() external view returns(uint256 createBlock, uint256 recentlyUsedBlock);
                      // Query creator
                      function checkOwner() external view returns(address);
                      function totalSupply() external view returns (uint256);
                      function balanceOf(address account) external view returns (uint256);
                      function transfer(address recipient, uint256 amount) external returns (bool);
                      function allowance(address owner, address spender) external view returns (uint256);
                      function approve(address spender, uint256 amount) external returns (bool);
                      function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
                      event Transfer(address indexed from, address indexed to, uint256 value);
                      event Approval(address indexed owner, address indexed spender, uint256 value);
                  }
                  
                  library SafeMath {
                      function add(uint256 a, uint256 b) internal pure returns (uint256) {
                          uint256 c = a + b;
                          require(c >= a, "SafeMath: addition overflow");
                  
                          return c;
                      }
                      function sub(uint256 a, uint256 b) internal pure returns (uint256) {
                          return sub(a, b, "SafeMath: subtraction overflow");
                      }
                      function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
                          require(b <= a, errorMessage);
                          uint256 c = a - b;
                  
                          return c;
                      }
                      function mul(uint256 a, uint256 b) internal pure returns (uint256) {
                          if (a == 0) {
                              return 0;
                          }
                          uint256 c = a * b;
                          require(c / a == b, "SafeMath: multiplication overflow");
                  
                          return c;
                      }
                      function div(uint256 a, uint256 b) internal pure returns (uint256) {
                          return div(a, b, "SafeMath: division by zero");
                      }
                      function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
                          require(b > 0, errorMessage);
                          uint256 c = a / b;
                          return c;
                      }
                      function mod(uint256 a, uint256 b) internal pure returns (uint256) {
                          return mod(a, b, "SafeMath: modulo by zero");
                      }
                      function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
                          require(b != 0, errorMessage);
                          return a % b;
                      }
                  }
                  
                  library address_make_payable {
                     function make_payable(address x) internal pure returns (address payable) {
                        return address(uint160(x));
                     }
                  }

                  File 9 of 11: NEST_NodeAssignment
                  pragma solidity 0.5.10;
                  
                  /**
                   * @title Node assignment contract
                   */
                  contract NEST_NodeAssignment {
                      
                      using SafeMath for uint256;
                      IBMapping mappingContract;                              //  Mapping contract
                      IBNEST nestContract;                                    //  NEST contract
                      SuperMan supermanContract;                              //  NestNode contract
                      NEST_NodeSave nodeSave;                                 //  NestNode save contract
                      NEST_NodeAssignmentData nodeAssignmentData;             //  NestNode data assignment contract
                  
                      /**
                      * @dev Initialization method
                      * @param map Voting contract address
                      */
                      constructor (address map) public {
                          mappingContract = IBMapping(map); 
                          nestContract = IBNEST(address(mappingContract.checkAddress("nest")));
                          supermanContract = SuperMan(address(mappingContract.checkAddress("nestNode")));
                          nodeSave = NEST_NodeSave(address(mappingContract.checkAddress("nestNodeSave")));
                          nodeAssignmentData = NEST_NodeAssignmentData(address(mappingContract.checkAddress("nodeAssignmentData")));
                      }
                      
                      /**
                      * @dev Reset voting contract
                      * @param map Voting contract address
                      */
                      function changeMapping(address map) public onlyOwner{
                          mappingContract = IBMapping(map); 
                          nestContract = IBNEST(address(mappingContract.checkAddress("nest")));
                          supermanContract = SuperMan(address(mappingContract.checkAddress("nestNode")));
                          nodeSave = NEST_NodeSave(address(mappingContract.checkAddress("nestNodeSave")));
                          nodeAssignmentData = NEST_NodeAssignmentData(address(mappingContract.checkAddress("nodeAssignmentData")));
                      }
                      
                      /**
                      * @dev Deposit NEST token
                      * @param amount Amount of deposited NEST
                      */
                      function bookKeeping(uint256 amount) public {
                          require(amount > 0);
                          require(nestContract.transferFrom(address(msg.sender), address(nodeSave), amount));
                          nodeAssignmentData.addNest(amount);
                      }
                      
                      // NestNode receive and settlement
                      function nodeGet() public {
                          require(address(msg.sender) == address(tx.origin));
                          require(supermanContract.balanceOf(address(msg.sender)) > 0);
                          uint256 allAmount = nodeAssignmentData.checkNodeAllAmount();
                          uint256 amount = allAmount.sub(nodeAssignmentData.checkNodeLatestAmount(address(msg.sender)));
                          uint256 getAmount = amount.mul(supermanContract.balanceOf(address(msg.sender))).div(1500);
                          require(nestContract.balanceOf(address(nodeSave)) >= getAmount);
                          nodeSave.turnOut(getAmount,address(msg.sender));
                          nodeAssignmentData.addNodeLatestAmount(address(msg.sender),allAmount);
                      }
                      
                      // NestNode transfer settlement
                      function nodeCount(address fromAdd, address toAdd) public {
                          require(address(supermanContract) == address(msg.sender));
                          require(supermanContract.balanceOf(address(fromAdd)) > 0);
                          uint256 allAmount = nodeAssignmentData.checkNodeAllAmount();
                          uint256 amountFrom = allAmount.sub(nodeAssignmentData.checkNodeLatestAmount(address(fromAdd)));
                          uint256 getAmountFrom = amountFrom.mul(supermanContract.balanceOf(address(fromAdd))).div(1500);
                          if (nestContract.balanceOf(address(nodeSave)) >= getAmountFrom) {
                              nodeSave.turnOut(getAmountFrom,address(fromAdd));
                              nodeAssignmentData.addNodeLatestAmount(address(fromAdd),allAmount);
                          }
                          uint256 amountTo = allAmount.sub(nodeAssignmentData.checkNodeLatestAmount(address(toAdd)));
                          uint256 getAmountTo = amountTo.mul(supermanContract.balanceOf(address(toAdd))).div(1500);
                          if (nestContract.balanceOf(address(nodeSave)) >= getAmountTo) {
                              nodeSave.turnOut(getAmountTo,address(toAdd));
                              nodeAssignmentData.addNodeLatestAmount(address(toAdd),allAmount);
                          }
                      }
                      
                      // NestNode receivable amount
                      function checkNodeNum() public view returns (uint256) {
                           uint256 allAmount = nodeAssignmentData.checkNodeAllAmount();
                           uint256 amount = allAmount.sub(nodeAssignmentData.checkNodeLatestAmount(address(msg.sender)));
                           uint256 getAmount = amount.mul(supermanContract.balanceOf(address(msg.sender))).div(1500);
                           return getAmount; 
                      }
                      
                      // Administrator only
                      modifier onlyOwner(){
                          require(mappingContract.checkOwners(msg.sender));
                          _;
                      }
                  }
                  
                  // Mapping contract
                  contract IBMapping {
                      // Check address
                  	function checkAddress(string memory name) public view returns (address contractAddress);
                  	// Check whether an administrator
                  	function checkOwners(address man) public view returns (bool);
                  }
                  
                  // NEST node save contract
                  contract NEST_NodeSave {
                      function turnOut(uint256 amount, address to) public returns(uint256);
                  }
                  
                  // NestNode assignment data contract
                  contract NEST_NodeAssignmentData {
                      function addNest(uint256 amount) public;
                      function addNodeLatestAmount(address add ,uint256 amount) public;
                      function checkNodeAllAmount() public view returns (uint256);
                      function checkNodeLatestAmount(address add) public view returns (uint256);
                  }
                  
                  // NestNode contract
                  interface SuperMan {
                      function totalSupply() external view returns (uint256);
                      function balanceOf(address who) external view returns (uint256);
                      function allowance(address owner, address spender) external view returns (uint256);
                      function transfer(address to, uint256 value) external returns (bool);
                      function approve(address spender, uint256 value) external returns (bool);
                      function transferFrom(address from, address to, uint256 value) external returns (bool);
                      event Transfer(address indexed from, address indexed to, uint256 value);
                      event Approval(address indexed owner, address indexed spender, uint256 value);
                  }
                  
                  // NEST contract
                  contract IBNEST {
                      function totalSupply() public view returns (uint supply);
                      function balanceOf( address who ) public view returns (uint value);
                      function allowance( address owner, address spender ) public view returns (uint _allowance);
                      function transfer( address to, uint256 value) external;
                      function transferFrom( address from, address to, uint value) public returns (bool ok);
                      function approve( address spender, uint value ) public returns (bool ok);
                      event Transfer( address indexed from, address indexed to, uint value);
                      event Approval( address indexed owner, address indexed spender, uint value);
                  }
                  
                  /**
                   * @title SafeMath
                   * @dev Math operations with safety checks that revert on error
                   */
                  library SafeMath {
                      int256 constant private INT256_MIN = -2**255;
                  
                      /**
                      * @dev Multiplies two unsigned integers, reverts on overflow.
                      */
                      function mul(uint256 a, uint256 b) internal pure returns (uint256) {
                          // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
                          // benefit is lost if 'b' is also tested.
                          // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
                          if (a == 0) {
                              return 0;
                          }
                  
                          uint256 c = a * b;
                          require(c / a == b);
                  
                          return c;
                      }
                  
                      /**
                      * @dev Multiplies two signed integers, reverts on overflow.
                      */
                      function mul(int256 a, int256 b) internal pure returns (int256) {
                          // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
                          // benefit is lost if 'b' is also tested.
                          // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
                          if (a == 0) {
                              return 0;
                          }
                  
                          require(!(a == -1 && b == INT256_MIN)); // This is the only case of overflow not detected by the check below
                  
                          int256 c = a * b;
                          require(c / a == b);
                  
                          return c;
                      }
                  
                      /**
                      * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
                      */
                      function div(uint256 a, uint256 b) internal pure returns (uint256) {
                          // Solidity only automatically asserts when dividing by 0
                          require(b > 0);
                          uint256 c = a / b;
                          // assert(a == b * c + a % b); // There is no case in which this doesn't hold
                  
                          return c;
                      }
                  
                      /**
                      * @dev Integer division of two signed integers truncating the quotient, reverts on division by zero.
                      */
                      function div(int256 a, int256 b) internal pure returns (int256) {
                          require(b != 0); // Solidity only automatically asserts when dividing by 0
                          require(!(b == -1 && a == INT256_MIN)); // This is the only case of overflow
                  
                          int256 c = a / b;
                  
                          return c;
                      }
                  
                      /**
                      * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
                      */
                      function sub(uint256 a, uint256 b) internal pure returns (uint256) {
                          require(b <= a);
                          uint256 c = a - b;
                  
                          return c;
                      }
                  
                      /**
                      * @dev Subtracts two signed integers, reverts on overflow.
                      */
                      function sub(int256 a, int256 b) internal pure returns (int256) {
                          int256 c = a - b;
                          require((b >= 0 && c <= a) || (b < 0 && c > a));
                  
                          return c;
                      }
                  
                      /**
                      * @dev Adds two unsigned integers, reverts on overflow.
                      */
                      function add(uint256 a, uint256 b) internal pure returns (uint256) {
                          uint256 c = a + b;
                          require(c >= a);
                  
                          return c;
                      }
                  
                      /**
                      * @dev Adds two signed integers, reverts on overflow.
                      */
                      function add(int256 a, int256 b) internal pure returns (int256) {
                          int256 c = a + b;
                          require((b >= 0 && c >= a) || (b < 0 && c < a));
                  
                          return c;
                      }
                  
                      /**
                      * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
                      * reverts when dividing by zero.
                      */
                      function mod(uint256 a, uint256 b) internal pure returns (uint256) {
                          require(b != 0);
                          return a % b;
                      }
                  }

                  File 10 of 11: NEST_NodeAssignmentData
                  pragma solidity ^0.5.10;
                  
                  /**
                   * @title Guardian node nest storage
                   */
                  contract NEST_NodeSave {
                      IBMapping mappingContract;                      
                      IBNEST nestContract;                             
                      
                      /**
                      * @dev Initialization method
                      * @param map Mapping contract address
                      */
                      constructor (address map) public {
                          mappingContract = IBMapping(address(map));              
                          nestContract = IBNEST(address(mappingContract.checkAddress("nest")));            
                      }
                      
                      /**
                      * @dev Change mapping contract
                      * @param map Mapping contract address
                      */
                      function changeMapping(address map) public onlyOwner {
                          mappingContract = IBMapping(address(map));              
                          nestContract = IBNEST(address(mappingContract.checkAddress("nest")));            
                      }
                      
                      /**
                      * @dev Transfer out nest
                      * @param amount Transfer out quantity
                      * @param to Transfer out target
                      * @return Actual transfer out quantity
                      */
                      function turnOut(uint256 amount, address to) public onlyMiningCalculation returns(uint256) {
                          uint256 leftNum = nestContract.balanceOf(address(this));
                          if (leftNum >= amount) {
                              nestContract.transfer(to, amount);
                              return amount;
                          } else {
                              return 0;
                          }
                      }
                      
                      modifier onlyOwner(){
                          require(mappingContract.checkOwners(msg.sender) == true);
                          _;
                      }
                  
                      modifier onlyMiningCalculation(){
                          require(address(mappingContract.checkAddress("nodeAssignment")) == msg.sender);
                          _;
                      }
                      
                  }
                  
                  /**
                   * @title Guardian node receives data
                   */
                  contract NEST_NodeAssignmentData {
                      using SafeMath for uint256;
                      IBMapping mappingContract;              
                      uint256 nodeAllAmount = 9546345842385995696603;                                 
                      mapping(address => uint256) nodeLatestAmount;               
                      
                      /**
                      * @dev Initialization method
                      * @param map Mapping contract address
                      */
                      constructor (address map) public {
                          mappingContract = IBMapping(map); 
                      }
                      
                      /**
                      * @dev Change mapping contract
                      * @param map Mapping contract address
                      */
                      function changeMapping(address map) public onlyOwner{
                          mappingContract = IBMapping(map); 
                      }
                      
                      //  Add nest
                      function addNest(uint256 amount) public onlyNodeAssignment {
                          nodeAllAmount = nodeAllAmount.add(amount);
                      }
                      
                      //  View cumulative total
                      function checkNodeAllAmount() public view returns (uint256) {
                          return nodeAllAmount;
                      }
                      
                      //  Record last received quantity
                      function addNodeLatestAmount(address add ,uint256 amount) public onlyNodeAssignment {
                          nodeLatestAmount[add] = amount;
                      }
                      
                      //  View last received quantity
                      function checkNodeLatestAmount(address add) public view returns (uint256) {
                          return nodeLatestAmount[address(add)];
                      }
                      
                      modifier onlyOwner(){
                          require(mappingContract.checkOwners(msg.sender) == true);
                          _;
                      }
                      
                      modifier onlyNodeAssignment(){
                          require(address(msg.sender) == address(mappingContract.checkAddress("nodeAssignment")));
                          _;
                      }
                  }
                  
                  /**
                   * @title Guardian node assignment
                   */
                  contract NEST_NodeAssignment {
                      
                      using SafeMath for uint256;
                      IBMapping mappingContract;  
                      IBNEST nestContract;                                   
                      SuperMan supermanContract;                              
                      NEST_NodeSave nodeSave;
                      NEST_NodeAssignmentData nodeAssignmentData;
                  
                      /**
                      * @dev Initialization method
                      * @param map Mapping contract address
                      */
                      constructor (address map) public {
                          mappingContract = IBMapping(map); 
                          nestContract = IBNEST(address(mappingContract.checkAddress("nest")));
                          supermanContract = SuperMan(address(mappingContract.checkAddress("nestNode")));
                          nodeSave = NEST_NodeSave(address(mappingContract.checkAddress("nestNodeSave")));
                          nodeAssignmentData = NEST_NodeAssignmentData(address(mappingContract.checkAddress("nodeAssignmentData")));
                      }
                      
                      /**
                      * @dev Change mapping contract
                      * @param map Mapping contract address
                      */
                      function changeMapping(address map) public onlyOwner{
                          mappingContract = IBMapping(map); 
                          nestContract = IBNEST(address(mappingContract.checkAddress("nest")));
                          supermanContract = SuperMan(address(mappingContract.checkAddress("nestNode")));
                          nodeSave = NEST_NodeSave(address(mappingContract.checkAddress("nestNodeSave")));
                          nodeAssignmentData = NEST_NodeAssignmentData(address(mappingContract.checkAddress("nodeAssignmentData")));
                      }
                      
                      /**
                      * @dev Deposit in nest
                      * @param amount Quantity deposited in nest
                      */
                      function bookKeeping(uint256 amount) public {
                          require(amount > 0);
                          require(nestContract.balanceOf(address(msg.sender)) >= amount);
                          require(nestContract.allowance(address(msg.sender), address(this)) >= amount);
                          require(nestContract.transferFrom(address(msg.sender), address(nodeSave), amount));
                          nodeAssignmentData.addNest(amount);
                      }
                      
                      /**
                      * @dev Guardian node collection
                      */
                      function nodeGet() public {
                          require(address(msg.sender) == address(tx.origin));
                          require(supermanContract.balanceOf(address(msg.sender)) > 0);
                          uint256 allAmount = nodeAssignmentData.checkNodeAllAmount();
                          uint256 amount = allAmount.sub(nodeAssignmentData.checkNodeLatestAmount(address(msg.sender)));
                          uint256 getAmount = amount.mul(supermanContract.balanceOf(address(msg.sender))).div(1500);
                          require(nestContract.balanceOf(address(nodeSave)) >= getAmount);
                          nodeSave.turnOut(getAmount,address(msg.sender));
                          nodeAssignmentData.addNodeLatestAmount(address(msg.sender),allAmount);
                      }
                      
                      /**
                      * @dev Transfer settlement
                      * @param fromAdd Transfer out address
                      * @param toAdd Transfer in address
                      */
                      function nodeCount(address fromAdd, address toAdd) public {
                          require(address(supermanContract) == address(msg.sender));
                          require(supermanContract.balanceOf(address(fromAdd)) > 0);
                          uint256 allAmount = nodeAssignmentData.checkNodeAllAmount();
                          
                          uint256 amountFrom = allAmount.sub(nodeAssignmentData.checkNodeLatestAmount(address(fromAdd)));
                          uint256 getAmountFrom = amountFrom.mul(supermanContract.balanceOf(address(fromAdd))).div(1500);
                          require(nestContract.balanceOf(address(nodeSave)) >= getAmountFrom);
                          nodeSave.turnOut(getAmountFrom,address(fromAdd));
                          nodeAssignmentData.addNodeLatestAmount(address(fromAdd),allAmount);
                          
                          uint256 amountTo = allAmount.sub(nodeAssignmentData.checkNodeLatestAmount(address(toAdd)));
                          uint256 getAmountTo = amountTo.mul(supermanContract.balanceOf(address(toAdd))).div(1500);
                          require(nestContract.balanceOf(address(nodeSave)) >= getAmountTo);
                          nodeSave.turnOut(getAmountTo,address(toAdd));
                          nodeAssignmentData.addNodeLatestAmount(address(toAdd),allAmount);
                      }
                      
                      //  Amount available to the guardian node
                      function checkNodeNum() public view returns (uint256) {
                           uint256 allAmount = nodeAssignmentData.checkNodeAllAmount();
                           uint256 amount = allAmount.sub(nodeAssignmentData.checkNodeLatestAmount(address(msg.sender)));
                           uint256 getAmount = amount.mul(supermanContract.balanceOf(address(msg.sender))).div(1500);
                           return getAmount;
                      }
                      
                      modifier onlyOwner(){
                          require(mappingContract.checkOwners(msg.sender) == true);
                          _;
                      }
                  }
                  
                  
                  /**
                   * @title ERC20 interface
                   * @dev see https://github.com/ethereum/EIPs/issues/20
                   */
                  interface IERC20 {
                      function totalSupply() external view returns (uint256);
                  
                      function balanceOf(address who) external view returns (uint256);
                  
                      function allowance(address owner, address spender) external view returns (uint256);
                  
                      function transfer(address to, uint256 value) external returns (bool);
                  
                      function approve(address spender, uint256 value) external returns (bool);
                  
                      function transferFrom(address from, address to, uint256 value) external returns (bool);
                  
                      event Transfer(address indexed from, address indexed to, uint256 value);
                  
                      event Approval(address indexed owner, address indexed spender, uint256 value);
                      
                  }
                  
                  /**
                   * @title Standard ERC20 token
                   *
                   * @dev Implementation of the basic standard token.
                   * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
                   * Originally based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
                   *
                   * This implementation emits additional Approval events, allowing applications to reconstruct the allowance status for
                   * all accounts just by listening to said events. Note that this isn't required by the specification, and other
                   * compliant implementations may not do it.
                   */
                  contract SuperMan is IERC20 {
                      using SafeMath for uint256;
                  
                      mapping (address => uint256) private _balances;
                  
                      mapping (address => mapping (address => uint256)) private _allowed;
                      
                      IBMapping mappingContract;  //映射合约
                  
                      uint256 private _totalSupply = 1500;
                      string public name = "NestNode";
                      string public symbol = "NN";
                      uint8 public decimals = 0;
                  
                      constructor (address map) public {
                      	_balances[msg.sender] = _totalSupply;
                      	mappingContract = IBMapping(map); 
                      }
                      
                      function changeMapping(address map) public onlyOwner{
                          mappingContract = IBMapping(map);
                      }
                      
                      /**
                      * @dev Total number of tokens in existence
                      */
                      function totalSupply() public view returns (uint256) {
                          return _totalSupply;
                      }
                  
                      /**
                      * @dev Gets the balance of the specified address.
                      * @param owner The address to query the balance of.
                      * @return An uint256 representing the amount owned by the passed address.
                      */
                      function balanceOf(address owner) public view returns (uint256) {
                          return _balances[owner];
                      }
                  
                      /**
                       * @dev Function to check the amount of tokens that an owner allowed to a spender.
                       * @param owner address The address which owns the funds.
                       * @param spender address The address which will spend the funds.
                       * @return A uint256 specifying the amount of tokens still available for the spender.
                       */
                      function allowance(address owner, address spender) public view returns (uint256) {
                          return _allowed[owner][spender];
                      }
                  
                      /**
                      * @dev Transfer token for a specified address
                      * @param to The address to transfer to.
                      * @param value The amount to be transferred.
                      */
                      function transfer(address to, uint256 value) public returns (bool) {
                          _transfer(msg.sender, to, value);
                          return true;
                      }
                  
                      /**
                       * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
                       * Beware that changing an allowance with this method brings the risk that someone may use both the old
                       * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
                       * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
                       * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
                       * @param spender The address which will spend the funds.
                       * @param value The amount of tokens to be spent.
                       */
                      function approve(address spender, uint256 value) public returns (bool) {
                          require(spender != address(0));
                  
                          _allowed[msg.sender][spender] = value;
                          emit Approval(msg.sender, spender, value);
                          return true;
                      }
                  
                      /**
                       * @dev Transfer tokens from one address to another.
                       * Note that while this function emits an Approval event, this is not required as per the specification,
                       * and other compliant implementations may not emit the event.
                       * @param from address The address which you want to send tokens from
                       * @param to address The address which you want to transfer to
                       * @param value uint256 the amount of tokens to be transferred
                       */
                      function transferFrom(address from, address to, uint256 value) public returns (bool) {
                          _allowed[from][msg.sender] = _allowed[from][msg.sender].sub(value);
                          _transfer(from, to, value);
                          emit Approval(from, msg.sender, _allowed[from][msg.sender]);
                          return true;
                      }
                  
                      /**
                       * @dev Increase the amount of tokens that an owner allowed to a spender.
                       * approve should be called when allowed_[_spender] == 0. To increment
                       * allowed value is better to use this function to avoid 2 calls (and wait until
                       * the first transaction is mined)
                       * From MonolithDAO Token.sol
                       * Emits an Approval event.
                       * @param spender The address which will spend the funds.
                       * @param addedValue The amount of tokens to increase the allowance by.
                       */
                      function increaseAllowance(address spender, uint256 addedValue) public returns (bool) {
                          require(spender != address(0));
                  
                          _allowed[msg.sender][spender] = _allowed[msg.sender][spender].add(addedValue);
                          emit Approval(msg.sender, spender, _allowed[msg.sender][spender]);
                          return true;
                      }
                  
                      /**
                       * @dev Decrease the amount of tokens that an owner allowed to a spender.
                       * approve should be called when allowed_[_spender] == 0. To decrement
                       * allowed value is better to use this function to avoid 2 calls (and wait until
                       * the first transaction is mined)
                       * From MonolithDAO Token.sol
                       * Emits an Approval event.
                       * @param spender The address which will spend the funds.
                       * @param subtractedValue The amount of tokens to decrease the allowance by.
                       */
                      function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) {
                          require(spender != address(0));
                  
                          _allowed[msg.sender][spender] = _allowed[msg.sender][spender].sub(subtractedValue);
                          emit Approval(msg.sender, spender, _allowed[msg.sender][spender]);
                          return true;
                      }
                  
                      /**
                      * @dev Transfer token for a specified addresses
                      * @param from The address to transfer from.
                      * @param to The address to transfer to.
                      * @param value The amount to be transferred.
                      */
                      function _transfer(address from, address to, uint256 value) internal {
                          require(to != address(0));
                          
                          NEST_NodeAssignment nodeAssignment = NEST_NodeAssignment(address(mappingContract.checkAddress("nodeAssignment")));
                          nodeAssignment.nodeCount(from, to);
                          
                          _balances[from] = _balances[from].sub(value);
                          _balances[to] = _balances[to].add(value);
                          emit Transfer(from, to, value);
                          
                          
                      }
                      
                      modifier onlyOwner(){
                          require(mappingContract.checkOwners(msg.sender) == true);
                          _;
                      }
                  }
                  
                  /**
                   * @title SafeMath
                   * @dev Math operations with safety checks that revert on error
                   */
                  library SafeMath {
                      int256 constant private INT256_MIN = -2**255;
                  
                      /**
                      * @dev Multiplies two unsigned integers, reverts on overflow.
                      */
                      function mul(uint256 a, uint256 b) internal pure returns (uint256) {
                          // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
                          // benefit is lost if 'b' is also tested.
                          // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
                          if (a == 0) {
                              return 0;
                          }
                  
                          uint256 c = a * b;
                          require(c / a == b);
                  
                          return c;
                      }
                  
                      /**
                      * @dev Multiplies two signed integers, reverts on overflow.
                      */
                      function mul(int256 a, int256 b) internal pure returns (int256) {
                          // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
                          // benefit is lost if 'b' is also tested.
                          // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
                          if (a == 0) {
                              return 0;
                          }
                  
                          require(!(a == -1 && b == INT256_MIN)); // This is the only case of overflow not detected by the check below
                  
                          int256 c = a * b;
                          require(c / a == b);
                  
                          return c;
                      }
                  
                      /**
                      * @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
                      */
                      function div(uint256 a, uint256 b) internal pure returns (uint256) {
                          // Solidity only automatically asserts when dividing by 0
                          require(b > 0);
                          uint256 c = a / b;
                          // assert(a == b * c + a % b); // There is no case in which this doesn't hold
                  
                          return c;
                      }
                  
                      /**
                      * @dev Integer division of two signed integers truncating the quotient, reverts on division by zero.
                      */
                      function div(int256 a, int256 b) internal pure returns (int256) {
                          require(b != 0); // Solidity only automatically asserts when dividing by 0
                          require(!(b == -1 && a == INT256_MIN)); // This is the only case of overflow
                  
                          int256 c = a / b;
                  
                          return c;
                      }
                  
                      /**
                      * @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
                      */
                      function sub(uint256 a, uint256 b) internal pure returns (uint256) {
                          require(b <= a);
                          uint256 c = a - b;
                  
                          return c;
                      }
                  
                      /**
                      * @dev Subtracts two signed integers, reverts on overflow.
                      */
                      function sub(int256 a, int256 b) internal pure returns (int256) {
                          int256 c = a - b;
                          require((b >= 0 && c <= a) || (b < 0 && c > a));
                  
                          return c;
                      }
                  
                      /**
                      * @dev Adds two unsigned integers, reverts on overflow.
                      */
                      function add(uint256 a, uint256 b) internal pure returns (uint256) {
                          uint256 c = a + b;
                          require(c >= a);
                  
                          return c;
                      }
                  
                      /**
                      * @dev Adds two signed integers, reverts on overflow.
                      */
                      function add(int256 a, int256 b) internal pure returns (int256) {
                          int256 c = a + b;
                          require((b >= 0 && c >= a) || (b < 0 && c < a));
                  
                          return c;
                      }
                  
                      /**
                      * @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
                      * reverts when dividing by zero.
                      */
                      function mod(uint256 a, uint256 b) internal pure returns (uint256) {
                          require(b != 0);
                          return a % b;
                      }
                  }
                  
                  contract IBMapping {
                  	function checkAddress(string memory name) public view returns (address contractAddress);
                  	function checkOwners(address man) public view returns (bool);
                  }
                  
                  contract IBNEST {
                      function totalSupply() public view returns (uint supply);
                      function balanceOf( address who ) public view returns (uint value);
                      function allowance( address owner, address spender ) public view returns (uint _allowance);
                  
                      function transfer( address to, uint256 value) external;
                      function transferFrom( address from, address to, uint value) public returns (bool ok);
                      function approve( address spender, uint value ) public returns (bool ok);
                  
                      event Transfer( address indexed from, address indexed to, uint value);
                      event Approval( address indexed owner, address indexed spender, uint value);
                      
                      function balancesStart() public view returns(uint256);
                      function balancesGetBool(uint256 num) public view returns(bool);
                      function balancesGetNext(uint256 num) public view returns(uint256);
                      function balancesGetValue(uint256 num) public view returns(address, uint256);
                  }

                  File 11 of 11: Nest_3_VoteFactory
                  pragma solidity 0.6.0;
                  
                  /**
                   * @title Voting factory + mapping
                   * @dev Vote creating method
                   */
                  contract Nest_3_VoteFactory {
                      using SafeMath for uint256;
                      
                      uint256 _limitTime = 7 days;                                    //  Vote duration
                      uint256 _NNLimitTime = 1 days;                                  //  NestNode raising time
                      uint256 _circulationProportion = 51;                            //  Proportion of votes to pass
                      uint256 _NNUsedCreate = 10;                                     //  The minimum number of NNs to create a voting contract
                      uint256 _NNCreateLimit = 100;                                   //  The minimum number of NNs needed to start voting
                      uint256 _emergencyTime = 0;                                     //  The emergency state start time
                      uint256 _emergencyTimeLimit = 3 days;                           //  The emergency state duration
                      uint256 _emergencyNNAmount = 1000;                              //  The number of NNs required to switch the emergency state
                      ERC20 _NNToken;                                                 //  NestNode Token
                      ERC20 _nestToken;                                               //  NestToken
                      mapping(string => address) _contractAddress;                    //  Voting contract mapping
                      mapping(address => bool) _modifyAuthority;                      //  Modify permissions
                      mapping(address => address) _myVote;                            //  Personal voting address
                      mapping(address => uint256) _emergencyPerson;                   //  Emergency state personal voting number
                      mapping(address => bool) _contractData;                         //  Voting contract data
                      bool _stateOfEmergency = false;                                 //  Emergency state
                      address _destructionAddress;                                    //  Destroy contract address
                  
                      event ContractAddress(address contractAddress);
                      
                      /**
                      * @dev Initialization method
                      */
                      constructor () public {
                          _modifyAuthority[address(msg.sender)] = true;
                      }
                      
                      /**
                      * @dev Reset contract
                      */
                      function changeMapping() public onlyOwner {
                          _NNToken = ERC20(checkAddress("nestNode"));
                          _destructionAddress = address(checkAddress("nest.v3.destruction"));
                          _nestToken = ERC20(address(checkAddress("nest")));
                      }
                      
                      /**
                      * @dev Create voting contract
                      * @param implementContract The executable contract address for voting
                      * @param nestNodeAmount Number of NNs to pledge
                      */
                      function createVote(address implementContract, uint256 nestNodeAmount) public {
                          require(address(tx.origin) == address(msg.sender), "It can't be a contract");
                          require(nestNodeAmount >= _NNUsedCreate);
                          Nest_3_VoteContract newContract = new Nest_3_VoteContract(implementContract, _stateOfEmergency, nestNodeAmount);
                          require(_NNToken.transferFrom(address(tx.origin), address(newContract), nestNodeAmount), "Authorization transfer failed");
                          _contractData[address(newContract)] = true;
                          emit ContractAddress(address(newContract));
                      }
                      
                      /**
                      * @dev Use NEST to vote
                      * @param contractAddress Vote contract address
                      */
                      function nestVote(address contractAddress) public {
                          require(address(msg.sender) == address(tx.origin), "It can't be a contract");
                          require(_contractData[contractAddress], "It's not a voting contract");
                          require(!checkVoteNow(address(msg.sender)));
                          Nest_3_VoteContract newContract = Nest_3_VoteContract(contractAddress);
                          newContract.nestVote();
                          _myVote[address(tx.origin)] = contractAddress;
                      }
                      
                      /**
                      * @dev Vote using NestNode Token
                      * @param contractAddress Vote contract address
                      * @param NNAmount Amount of NNs to pledge
                      */
                      function nestNodeVote(address contractAddress, uint256 NNAmount) public {
                          require(address(msg.sender) == address(tx.origin), "It can't be a contract");
                          require(_contractData[contractAddress], "It's not a voting contract");
                          Nest_3_VoteContract newContract = Nest_3_VoteContract(contractAddress);
                          require(_NNToken.transferFrom(address(tx.origin), address(newContract), NNAmount), "Authorization transfer failed");
                          newContract.nestNodeVote(NNAmount);
                      }
                      
                      /**
                      * @dev Excecute contract
                      * @param contractAddress Vote contract address
                      */
                      function startChange(address contractAddress) public {
                          require(address(msg.sender) == address(tx.origin), "It can't be a contract");
                          require(_contractData[contractAddress], "It's not a voting contract");
                          Nest_3_VoteContract newContract = Nest_3_VoteContract(contractAddress);
                          require(_stateOfEmergency == newContract.checkStateOfEmergency());
                          addSuperManPrivate(address(newContract));
                          newContract.startChange();
                          deleteSuperManPrivate(address(newContract));
                      }
                      
                      /**
                      * @dev Switch emergency state-transfer in NestNode Token
                      * @param amount Amount of NNs to transfer
                      */
                      function sendNestNodeForStateOfEmergency(uint256 amount) public {
                          require(_NNToken.transferFrom(address(tx.origin), address(this), amount));
                          _emergencyPerson[address(tx.origin)] = _emergencyPerson[address(tx.origin)].add(amount);
                      }
                      
                      /**
                      * @dev Switch emergency state-transfer out NestNode Token
                      */
                      function turnOutNestNodeForStateOfEmergency() public {
                          require(_emergencyPerson[address(tx.origin)] > 0);
                          require(_NNToken.transfer(address(tx.origin), _emergencyPerson[address(tx.origin)]));
                          _emergencyPerson[address(tx.origin)] = 0;
                          uint256 nestAmount = _nestToken.balanceOf(address(this));
                          require(_nestToken.transfer(address(_destructionAddress), nestAmount));
                      }
                      
                      /**
                      * @dev Modify emergency state
                      */
                      function changeStateOfEmergency() public {
                          if (_stateOfEmergency) {
                              require(now > _emergencyTime.add(_emergencyTimeLimit));
                              _stateOfEmergency = false;
                              _emergencyTime = 0;
                          } else {
                              require(_emergencyPerson[address(msg.sender)] > 0);
                              require(_NNToken.balanceOf(address(this)) >= _emergencyNNAmount);
                              _stateOfEmergency = true;
                              _emergencyTime = now;
                          }
                      }
                      
                      /**
                      * @dev Check whether participating in the voting
                      * @param user Address to check
                      * @return bool Whether voting
                      */
                      function checkVoteNow(address user) public view returns (bool) {
                          if (_myVote[user] == address(0x0)) {
                              return false;
                          } else {
                              Nest_3_VoteContract vote = Nest_3_VoteContract(_myVote[user]);
                              if (vote.checkContractEffective() || vote.checkPersonalAmount(user) == 0) {
                                  return false;
                              }
                              return true;
                          }
                      }
                      
                      /**
                      * @dev Check my voting
                      * @param user Address to check
                      * @return address Address recently participated in the voting contract address
                      */
                      function checkMyVote(address user) public view returns (address) {
                          return _myVote[user];
                      }
                      
                      //  Check the voting time
                      function checkLimitTime() public view returns (uint256) {
                          return _limitTime;
                      }
                      
                      //  Check the NestNode raising time
                      function checkNNLimitTime() public view returns (uint256) {
                          return _NNLimitTime;
                      }
                      
                      //  Check the voting proportion to pass
                      function checkCirculationProportion() public view returns (uint256) {
                          return _circulationProportion;
                      }
                      
                      //  Check the minimum number of NNs to create a voting contract
                      function checkNNUsedCreate() public view returns (uint256) {
                          return _NNUsedCreate;
                      }
                      
                      //  Check the minimum number of NNs raised to start a vote
                      function checkNNCreateLimit() public view returns (uint256) {
                          return _NNCreateLimit;
                      }
                      
                      //  Check whether in emergency state
                      function checkStateOfEmergency() public view returns (bool) {
                          return _stateOfEmergency;
                      }
                      
                      //  Check the start time of the emergency state
                      function checkEmergencyTime() public view returns (uint256) {
                          return _emergencyTime;
                      }
                      
                      //  Check the duration of the emergency state
                      function checkEmergencyTimeLimit() public view returns (uint256) {
                          return _emergencyTimeLimit;
                      }
                      
                      //  Check the amount of personal pledged NNs
                      function checkEmergencyPerson(address user) public view returns (uint256) {
                          return _emergencyPerson[user];
                      }
                      
                      //  Check the number of NNs required for the emergency
                      function checkEmergencyNNAmount() public view returns (uint256) {
                          return _emergencyNNAmount;
                      }
                      
                      //  Verify voting contract data
                      function checkContractData(address contractAddress) public view returns (bool) {
                          return _contractData[contractAddress];
                      }
                      
                      //  Modify voting time
                      function changeLimitTime(uint256 num) public onlyOwner {
                          require(num > 0, "Parameter needs to be greater than 0");
                          _limitTime = num;
                      }
                      
                      //  Modify the NestNode raising time
                      function changeNNLimitTime(uint256 num) public onlyOwner {
                          require(num > 0, "Parameter needs to be greater than 0");
                          _NNLimitTime = num;
                      }
                      
                      //  Modify the voting proportion
                      function changeCirculationProportion(uint256 num) public onlyOwner {
                          require(num > 0, "Parameter needs to be greater than 0");
                          _circulationProportion = num;
                      }
                      
                      //  Modify the minimum number of NNs to create a voting contract
                      function changeNNUsedCreate(uint256 num) public onlyOwner {
                          _NNUsedCreate = num;
                      }
                      
                      //  Modify the minimum number of NNs to raised to start a voting
                      function checkNNCreateLimit(uint256 num) public onlyOwner {
                          _NNCreateLimit = num;
                      }
                      
                      //  Modify the emergency state duration
                      function changeEmergencyTimeLimit(uint256 num) public onlyOwner {
                          require(num > 0);
                          _emergencyTimeLimit = num.mul(1 days);
                      }
                      
                      //  Modify the number of NNs required for emergency state
                      function changeEmergencyNNAmount(uint256 num) public onlyOwner {
                          require(num > 0);
                          _emergencyNNAmount = num;
                      }
                      
                      //  Check address
                      function checkAddress(string memory name) public view returns (address contractAddress) {
                          return _contractAddress[name];
                      }
                      
                      //  Add contract mapping address
                      function addContractAddress(string memory name, address contractAddress) public onlyOwner {
                          _contractAddress[name] = contractAddress;
                      }
                      
                      //  Add administrator address 
                      function addSuperMan(address superMan) public onlyOwner {
                          _modifyAuthority[superMan] = true;
                      }
                      function addSuperManPrivate(address superMan) private {
                          _modifyAuthority[superMan] = true;
                      }
                      
                      //  Delete administrator address
                      function deleteSuperMan(address superMan) public onlyOwner {
                          _modifyAuthority[superMan] = false;
                      }
                      function deleteSuperManPrivate(address superMan) private {
                          _modifyAuthority[superMan] = false;
                      }
                      
                      //  Delete voting contract data
                      function deleteContractData(address contractAddress) public onlyOwner {
                          _contractData[contractAddress] = false;
                      }
                      
                      //  Check whether the administrator
                      function checkOwners(address man) public view returns (bool) {
                          return _modifyAuthority[man];
                      }
                      
                      //  Administrator only
                      modifier onlyOwner() {
                          require(checkOwners(msg.sender), "No authority");
                          _;
                      }
                  }
                  
                  /**
                   * @title Voting contract
                   */
                  contract Nest_3_VoteContract {
                      using SafeMath for uint256;
                      
                      Nest_3_Implement _implementContract;                //  Executable contract
                      Nest_3_TokenSave _tokenSave;                        //  Lock-up contract
                      Nest_3_VoteFactory _voteFactory;                    //  Voting factory contract
                      Nest_3_TokenAbonus _tokenAbonus;                    //  Bonus logic contract
                      ERC20 _nestToken;                                   //  NestToken
                      ERC20 _NNToken;                                     //  NestNode Token
                      address _miningSave;                                //  Mining pool contract
                      address _implementAddress;                          //  Executable contract address
                      address _destructionAddress;                        //  Destruction contract address
                      uint256 _createTime;                                //  Creation time
                      uint256 _endTime;                                   //  End time
                      uint256 _totalAmount;                               //  Total votes
                      uint256 _circulation;                               //  Passed votes
                      uint256 _destroyedNest;                             //  Destroyed NEST
                      uint256 _NNLimitTime;                               //  NestNode raising time
                      uint256 _NNCreateLimit;                             //  Minimum number of NNs to create votes
                      uint256 _abonusTimes;                               //  Period number of used snapshot in emergency state
                      uint256 _allNNAmount;                               //  Total number of NNs
                      bool _effective = false;                            //  Whether vote is effective
                      bool _nestVote = false;                             //  Whether NEST vote can be performed
                      bool _isChange = false;                             //  Whether NEST vote is executed
                      bool _stateOfEmergency;                             //  Whether the contract is in emergency state
                      mapping(address => uint256) _personalAmount;        //  Number of personal votes
                      mapping(address => uint256) _personalNNAmount;      //  Number of NN personal votes
                      
                      /**
                      * @dev Initialization method
                      * @param contractAddress Executable contract address
                      * @param stateOfEmergency Whether in emergency state
                      * @param NNAmount Amount of NNs
                      */
                      constructor (address contractAddress, bool stateOfEmergency, uint256 NNAmount) public {
                          Nest_3_VoteFactory voteFactory = Nest_3_VoteFactory(address(msg.sender));
                          _voteFactory = voteFactory;
                          _nestToken = ERC20(voteFactory.checkAddress("nest"));
                          _NNToken = ERC20(voteFactory.checkAddress("nestNode"));
                          _implementContract = Nest_3_Implement(address(contractAddress));
                          _implementAddress = address(contractAddress);
                          _destructionAddress = address(voteFactory.checkAddress("nest.v3.destruction"));
                          _personalNNAmount[address(tx.origin)] = NNAmount;
                          _allNNAmount = NNAmount;
                          _createTime = now;                                    
                          _endTime = _createTime.add(voteFactory.checkLimitTime());
                          _NNLimitTime = voteFactory.checkNNLimitTime();
                          _NNCreateLimit = voteFactory.checkNNCreateLimit();
                          _stateOfEmergency = stateOfEmergency;
                          if (stateOfEmergency) {
                              //  If in emergency state, read the last two periods of bonus lock-up and total circulation data
                              _tokenAbonus = Nest_3_TokenAbonus(voteFactory.checkAddress("nest.v3.tokenAbonus"));
                              _abonusTimes = _tokenAbonus.checkTimes().sub(2);
                              require(_abonusTimes > 0);
                              _circulation = _tokenAbonus.checkTokenAllValueHistory(address(_nestToken),_abonusTimes).mul(voteFactory.checkCirculationProportion()).div(100);
                          } else {
                              _miningSave = address(voteFactory.checkAddress("nest.v3.miningSave"));
                              _tokenSave = Nest_3_TokenSave(voteFactory.checkAddress("nest.v3.tokenSave"));
                              _circulation = (uint256(10000000000 ether).sub(_nestToken.balanceOf(address(_miningSave))).sub(_nestToken.balanceOf(address(_destructionAddress)))).mul(voteFactory.checkCirculationProportion()).div(100);
                          }
                          if (_allNNAmount >= _NNCreateLimit) {
                              _nestVote = true;
                          }
                      }
                      
                      /**
                      * @dev NEST voting
                      */
                      function nestVote() public onlyFactory {
                          require(now <= _endTime, "Voting time exceeded");
                          require(!_effective, "Vote in force");
                          require(_nestVote);
                          require(_personalAmount[address(tx.origin)] == 0, "Have voted");
                          uint256 amount;
                          if (_stateOfEmergency) {
                              //  If in emergency state, read the last two periods of bonus lock-up and total circulation data
                              amount = _tokenAbonus.checkTokenSelfHistory(address(_nestToken),_abonusTimes, address(tx.origin));
                          } else {
                              amount = _tokenSave.checkAmount(address(tx.origin), address(_nestToken));
                          }
                          _personalAmount[address(tx.origin)] = amount;
                          _totalAmount = _totalAmount.add(amount);
                          ifEffective();
                      }
                      
                      /**
                      * @dev NEST voting cancellation
                      */
                      function nestVoteCancel() public {
                          require(address(msg.sender) == address(tx.origin), "It can't be a contract");
                          require(now <= _endTime, "Voting time exceeded");
                          require(!_effective, "Vote in force");
                          require(_personalAmount[address(tx.origin)] > 0, "No vote");                     
                          _totalAmount = _totalAmount.sub(_personalAmount[address(tx.origin)]);
                          _personalAmount[address(tx.origin)] = 0;
                      }
                      
                      /**
                      * @dev  NestNode voting
                      * @param NNAmount Amount of NNs
                      */
                      function nestNodeVote(uint256 NNAmount) public onlyFactory {
                          require(now <= _createTime.add(_NNLimitTime), "Voting time exceeded");
                          require(!_nestVote);
                          _personalNNAmount[address(tx.origin)] = _personalNNAmount[address(tx.origin)].add(NNAmount);
                          _allNNAmount = _allNNAmount.add(NNAmount);
                          if (_allNNAmount >= _NNCreateLimit) {
                              _nestVote = true;
                          }
                      }
                      
                      /**
                      * @dev Withdrawing lock-up NNs
                      */
                      function turnOutNestNode() public {
                          if (_nestVote) {
                              //  Normal NEST voting
                              if (!_stateOfEmergency || !_effective) {
                                  //  Non-emergency state
                                  require(now > _endTime, "Vote unenforceable");
                              }
                          } else {
                              //  NN voting
                              require(now > _createTime.add(_NNLimitTime));
                          }
                          require(_personalNNAmount[address(tx.origin)] > 0);
                          //  Reverting back the NNs
                          require(_NNToken.transfer(address(tx.origin), _personalNNAmount[address(tx.origin)]));
                          _personalNNAmount[address(tx.origin)] = 0;
                          //  Destroying NEST Tokens 
                          uint256 nestAmount = _nestToken.balanceOf(address(this));
                          _destroyedNest = _destroyedNest.add(nestAmount);
                          require(_nestToken.transfer(address(_destructionAddress), nestAmount));
                      }
                      
                      /**
                      * @dev Execute the contract
                      */
                      function startChange() public onlyFactory {
                          require(!_isChange);
                          _isChange = true;
                          if (_stateOfEmergency) {
                              require(_effective, "Vote unenforceable");
                          } else {
                              require(_effective && now > _endTime, "Vote unenforceable");
                          }
                          //  Add the executable contract to the administrator list
                          _voteFactory.addSuperMan(address(_implementContract));
                          //  Execute
                          _implementContract.doit();
                          //  Delete the authorization
                          _voteFactory.deleteSuperMan(address(_implementContract));
                      }
                      
                      /**
                      * @dev check whether the vote is effective
                      */
                      function ifEffective() private {
                          if (_totalAmount >= _circulation) {
                              _effective = true;
                          }
                      }
                      
                      /**
                      * @dev Check whether the vote is over
                      */
                      function checkContractEffective() public view returns (bool) {
                          if (_effective || now > _endTime) {
                              return true;
                          } 
                          return false;
                      }
                      
                      //  Check the executable implement contract address
                      function checkImplementAddress() public view returns (address) {
                          return _implementAddress;
                      }
                      
                      //  Check the voting start time
                      function checkCreateTime() public view returns (uint256) {
                          return _createTime;
                      }
                      
                      //  Check the voting end time
                      function checkEndTime() public view returns (uint256) {
                          return _endTime;
                      }
                      
                      //  Check the current total number of votes
                      function checkTotalAmount() public view returns (uint256) {
                          return _totalAmount;
                      }
                      
                      //  Check the number of votes to pass
                      function checkCirculation() public view returns (uint256) {
                          return _circulation;
                      }
                      
                      //  Check the number of personal votes
                      function checkPersonalAmount(address user) public view returns (uint256) {
                          return _personalAmount[user];
                      }
                      
                      //  Check the destroyed NEST
                      function checkDestroyedNest() public view returns (uint256) {
                          return _destroyedNest;
                      }
                      
                      //  Check whether the contract is effective
                      function checkEffective() public view returns (bool) {
                          return _effective;
                      }
                      
                      //  Check whether in emergency state
                      function checkStateOfEmergency() public view returns (bool) {
                          return _stateOfEmergency;
                      }
                      
                      //  Check NestNode raising time
                      function checkNNLimitTime() public view returns (uint256) {
                          return _NNLimitTime;
                      }
                      
                      //  Check the minimum number of NNs to create a vote
                      function checkNNCreateLimit() public view returns (uint256) {
                          return _NNCreateLimit;
                      }
                      
                      //  Check the period number of snapshot used in the emergency state
                      function checkAbonusTimes() public view returns (uint256) {
                          return _abonusTimes;
                      }
                      
                      //  Check number of personal votes
                      function checkPersonalNNAmount(address user) public view returns (uint256) {
                          return _personalNNAmount[address(user)];
                      }
                      
                      //  Check the total number of NNs
                      function checkAllNNAmount() public view returns (uint256) {
                          return _allNNAmount;
                      }
                      
                      //  Check whether NEST voting is available
                      function checkNestVote() public view returns (bool) {
                          return _nestVote;
                      }
                      
                      //  Check whether it has been excecuted
                      function checkIsChange() public view returns (bool) {
                          return _isChange;
                      }
                      
                      //  Vote Factory contract only
                      modifier onlyFactory() {
                          require(address(_voteFactory) == address(msg.sender), "No authority");
                          _;
                      }
                  }
                  
                  //  Executable contract
                  interface Nest_3_Implement {
                      //  Execute
                      function doit() external;
                  }
                  
                  //  NEST lock-up contract
                  interface Nest_3_TokenSave {
                      //  Check lock-up amount
                      function checkAmount(address sender, address token) external view returns (uint256);
                  }
                  
                  //  Bonus logic contract
                  interface Nest_3_TokenAbonus {
                      //  Check NEST circulation snapshot
                      function checkTokenAllValueHistory(address token, uint256 times) external view returns (uint256);
                      //  Check NEST user balance snapshot
                      function checkTokenSelfHistory(address token, uint256 times, address user) external view returns (uint256);
                      //  Check bonus ledger period
                      function checkTimes() external view returns (uint256);
                  }
                  
                  //  Erc20 contract
                  interface ERC20 {
                      function totalSupply() external view returns (uint256);
                      function balanceOf(address account) external view returns (uint256);
                      function transfer(address recipient, uint256 amount) external returns (bool);
                      function allowance(address owner, address spender) external view returns (uint256);
                      function approve(address spender, uint256 amount) external returns (bool);
                      function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
                      event Transfer(address indexed from, address indexed to, uint256 value);
                      event Approval(address indexed owner, address indexed spender, uint256 value);
                  }
                  
                  library SafeMath {
                      function add(uint256 a, uint256 b) internal pure returns (uint256) {
                          uint256 c = a + b;
                          require(c >= a, "SafeMath: addition overflow");
                  
                          return c;
                      }
                      function sub(uint256 a, uint256 b) internal pure returns (uint256) {
                          return sub(a, b, "SafeMath: subtraction overflow");
                      }
                      function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
                          require(b <= a, errorMessage);
                          uint256 c = a - b;
                  
                          return c;
                      }
                      function mul(uint256 a, uint256 b) internal pure returns (uint256) {
                          if (a == 0) {
                              return 0;
                          }
                          uint256 c = a * b;
                          require(c / a == b, "SafeMath: multiplication overflow");
                  
                          return c;
                      }
                      function div(uint256 a, uint256 b) internal pure returns (uint256) {
                          return div(a, b, "SafeMath: division by zero");
                      }
                      function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
                          require(b > 0, errorMessage);
                          uint256 c = a / b;
                          return c;
                      }
                      function mod(uint256 a, uint256 b) internal pure returns (uint256) {
                          return mod(a, b, "SafeMath: modulo by zero");
                      }
                      function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
                          require(b != 0, errorMessage);
                          return a % b;
                      }
                  }