ETH Price: $3,082.19 (-0.64%)
Gas: 4 Gwei

Transaction Decoder

Block:
9733166 at Mar-24-2020 08:36:52 AM +UTC
Transaction Fee:
0.0018618292 ETH $5.74
Gas Used:
241,796 Gas / 7.7 Gwei

Emitted Events:

62 TetherToken.Transfer( from=0x38a7d1c1F600c9336f88B38da603688Dd1744418, to=[Sender] 0xa1f3aaa3a96db3b20dbde1b5f8e3bd564df8ae7c, value=1411000000 )
63 IBNEST.Transfer( from=NEST_MiningSave, to=[Receiver] NEST_3_OfferFactory, value=16200000000000000000000 )
64 NEST_3_OrePoolLogic.miningLog( blockNum=9733128, tokenAddress=TetherToken, miningEthAll=100000000000000000, miningEthSelf=100000000000000000, tokenNum=1 )
65 IBNEST.Transfer( from=[Receiver] NEST_3_OfferFactory, to=[Sender] 0xa1f3aaa3a96db3b20dbde1b5f8e3bd564df8ae7c, value=12960000000000000000000 )
66 IBNEST.Approval( owner=[Receiver] NEST_3_OfferFactory, spender=NEST_NodeAssignment, value=2430000000000000000000 )
67 IBNEST.Transfer( from=[Receiver] NEST_3_OfferFactory, to=NEST_NodeSave, value=2430000000000000000000 )
68 IBNEST.Transfer( from=[Receiver] NEST_3_OfferFactory, to=0x6756927922D2A32cB799F261e4aBC47652CDE54b, value=810000000000000000000 )

Account State Difference:

  Address   Before After State Difference Code
0x04abEdA2...c74ddC74C
0x38a7d1c1...Dd1744418 10 Eth0 Eth10
0xa1f3aAa3...64dF8aE7c
5.317142411923399334 Eth
Nonce: 14815
15.315280582723399334 Eth
Nonce: 14816
9.9981381708
0xb086F99E...17BBc6cbC
0xdAC17F95...13D831ec7
(BTC.com Pool)
424.821588064651276281 Eth424.823449893851276281 Eth0.0018618292

Execution Trace

NEST_3_OfferFactory.turnOut( contractAddress=0x38a7d1c1F600c9336f88B38da603688Dd1744418 )
  • NEST_3_OfferData.checkContract( contractAddress=0x38a7d1c1F600c9336f88B38da603688Dd1744418 ) => ( True )
  • 0x38a7d1c1f600c9336f88b38da603688dd1744418.CALL( )
    • NEST_3_OfferFactory.STATICCALL( )
    • TetherToken.balanceOf( who=0x38a7d1c1F600c9336f88B38da603688Dd1744418 ) => ( 1411000000 )
    • ETH 10 0xa1f3aaa3a96db3b20dbde1b5f8e3bd564df8ae7c.CALL( )
    • TetherToken.transfer( _to=0xa1f3aAa3A96Db3b20DBDE1B5f8E3bD564dF8aE7c, _value=1411000000 )
    • 0x38a7d1c1f600c9336f88b38da603688dd1744418.STATICCALL( )
    • 0x38a7d1c1f600c9336f88b38da603688dd1744418.STATICCALL( )
    • 0x38a7d1c1f600c9336f88b38da603688dd1744418.STATICCALL( )
    • NEST_3_OrePoolLogic.mining( amount=100000000000000000, blockNum=9733128, target=0x4F391C202a906EED9e2b63fDd387F28E952782E2, token=0xdAC17F958D2ee523a2206206994597C13D831ec7 ) => ( 16200000000000000000000 )
      • NEST_MiningSave.turnOut( amount=16200000000000000000000, to=0x4F391C202a906EED9e2b63fDd387F28E952782E2 ) => ( 16200000000000000000000 )
        • IBMapping.checkAddress( name=miningCalculation ) => ( contractAddress=0x9C3C7bcf8993A58410016E29882c78B552D5C9b4 )
        • IBNEST.balanceOf( _owner=0x923F80828663E44e0FFD5eB499686dC1CCc78476 ) => ( 8684775404188881024933952036 )
          • IterableMapping.4c5e1cae( )
          • IBNEST.transfer( _to=0x4F391C202a906EED9e2b63fDd387F28E952782E2, _value=16200000000000000000000 ) => ( True )
            • IterableMapping.4c5e1cae( )
            • IterableMapping.4c5e1cae( )
            • IterableMapping.ab517b4f( )
            • IterableMapping.4c5e1cae( )
            • IterableMapping.ab517b4f( )
            • IBNEST.transfer( _to=0xa1f3aAa3A96Db3b20DBDE1B5f8E3bD564dF8aE7c, _value=12960000000000000000000 ) => ( True )
              • IterableMapping.4c5e1cae( )
              • IterableMapping.4c5e1cae( )
              • IterableMapping.ab517b4f( )
              • IterableMapping.4c5e1cae( )
              • IterableMapping.ab517b4f( )
              • IBNEST.approve( _spender=0x472c31697633daCd24C4674b4571d4A393d54870, _value=2430000000000000000000 ) => ( True )
              • NEST_NodeAssignment.bookKeeping( amount=2430000000000000000000 )
                • IBNEST.balanceOf( _owner=0x4F391C202a906EED9e2b63fDd387F28E952782E2 ) => ( 3240000000000000000000 )
                  • IterableMapping.4c5e1cae( )
                  • IBNEST.allowance( _owner=0x4F391C202a906EED9e2b63fDd387F28E952782E2, _spender=0x472c31697633daCd24C4674b4571d4A393d54870 ) => ( 2430000000000000000000 )
                  • IBNEST.transferFrom( _from=0x4F391C202a906EED9e2b63fDd387F28E952782E2, _to=0x101D8b63A081dFfF2B1364864345b7F071b052ac, _value=2430000000000000000000 ) => ( True )
                    • IterableMapping.4c5e1cae( )
                    • IterableMapping.4c5e1cae( )
                    • IterableMapping.ab517b4f( )
                    • IterableMapping.4c5e1cae( )
                    • IterableMapping.ab517b4f( )
                    • NEST_NodeAssignmentData.addNest( amount=2430000000000000000000 )
                      • IBMapping.checkAddress( name=nodeAssignment ) => ( contractAddress=0x472c31697633daCd24C4674b4571d4A393d54870 )
                      • IBNEST.transfer( _to=0x6756927922D2A32cB799F261e4aBC47652CDE54b, _value=810000000000000000000 ) => ( True )
                        • IterableMapping.4c5e1cae( )
                        • IterableMapping.4c5e1cae( )
                        • IterableMapping.ab517b4f( )
                        • IterableMapping.4c5e1cae( )
                        • IterableMapping.ab517b4f( )
                          File 1 of 11: NEST_3_OfferFactory
                          pragma solidity ^0.5.12;
                          
                          /**
                           * @title Quotation data contract
                           * @dev Verification of quotation contract
                           */
                          contract NEST_3_OfferData {
                          
                              mapping (address => bool) addressMapping;       //  Deployed quote contracts
                              NEST_2_Mapping mappingContract;                 //  Mapping contract
                              
                              /**
                              * @dev Initialization method
                              * @param map Mapping contract address
                              */
                              constructor(address map) public{
                                  mappingContract = NEST_2_Mapping(map);                                                      
                              }
                              
                              /**
                              * @dev Initialization method
                              * @param map Mapping contract address
                              */
                              function changeMapping(address map) public onlyOwner {
                                  mappingContract = NEST_2_Mapping(map);                                                    
                              }
                              
                              /**
                              * @dev Initialization method
                              * @param contractAddress Address of quotation contract
                              * @return existence of quotation contract
                              */
                              function checkContract(address contractAddress) public view returns (bool){
                                  require(contractAddress != address(0x0));
                                  return addressMapping[contractAddress];
                              }
                              
                              /**
                              * @dev Add quote contract address
                              * @param contractAddress Address of quotation contract
                              */
                              function addContractAddress(address contractAddress) public {
                                  require(address(mappingContract.checkAddress("offerFactory")) == msg.sender);
                                  addressMapping[contractAddress] = true;
                              }
                              
                              modifier onlyOwner(){
                                  require(mappingContract.checkOwners(msg.sender) == true);
                                  _;
                              }
                          }
                          
                          /**
                           * @title Quotation factory
                           * @dev Quotation mining
                           */
                          contract NEST_3_OfferFactory {
                              using SafeMath for uint256;
                              using address_make_payable for address;
                              mapping(address => bool) tokenAllow;                //  Insured mining token
                              NEST_2_Mapping mappingContract;                     //  Mapping contract
                              NEST_3_OfferData dataContract;                      //  Data contract
                              NEST_2_OfferPrice offerPrice;                       //  Price contract
                              NEST_3_OrePoolLogic orePoolLogic;                   //  Mining contract
                              NEST_NodeAssignment NNcontract;                     //  NestNode contract
                              ERC20 nestToken;                                    //  nestToken
                              address abonusAddress;                              //  Dividend pool
                              address coderAddress;                               //  Developer address
                              uint256 miningETH = 10;                             //  Quotation mining service charge mining proportion, 10 thousandths
                              uint256 tranEth = 2;                                //  Service charge proportion of the bill of lading, 2 ‰
                              uint256 blockLimit = 25;                            //  Block interval upper limit
                              uint256 tranAddition = 2;                           //  Transaction bonus
                              uint256 coderAmount = 5;                            //  Developer ratio
                              uint256 NNAmount = 15;                              //  Guardian node proportion
                              uint256 otherAmount = 80;                           //  Distributable proportion
                              uint256 leastEth = 1 ether;                         //  Minimum offer eth
                              uint256 offerSpan = 1 ether;                        //  Quotation eth span
                              
                              //  log Personal asset contract
                              event offerTokenContractAddress(address contractAddress);    
                              //  log Quotation contract, token address, ETH quantity, erc20 quantity     
                              event offerContractAddress(address contractAddress, address tokenAddress, uint256 ethAmount, uint256 erc20Amount); 
                              //  log Transaction, transaction initiator, transaction token address, transaction token quantity, purchase token address, purchase token quantity, traded quotation 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 map Mapping contract address
                              */
                              constructor (address map) public {
                                  mappingContract = NEST_2_Mapping(map);                                                      
                                  offerPrice = NEST_2_OfferPrice(address(mappingContract.checkAddress("offerPrice")));        
                                  orePoolLogic = NEST_3_OrePoolLogic(address(mappingContract.checkAddress("miningCalculation")));
                                  abonusAddress = mappingContract.checkAddress("abonus");
                                  nestToken = ERC20(mappingContract.checkAddress("nest"));                                        
                                  NNcontract = NEST_NodeAssignment(address(mappingContract.checkAddress("nodeAssignment")));      
                                  coderAddress = mappingContract.checkAddress("coder");
                                  dataContract = NEST_3_OfferData(address(mappingContract.checkAddress("offerData")));
                              }
                              
                              /**
                              * @dev Change mapping contract
                              * @param map Mapping contract address
                              */
                              function changeMapping(address map) public onlyOwner {
                                  mappingContract = NEST_2_Mapping(map);                                                          
                                  offerPrice = NEST_2_OfferPrice(address(mappingContract.checkAddress("offerPrice")));            
                                  orePoolLogic = NEST_3_OrePoolLogic(address(mappingContract.checkAddress("miningCalculation")));
                                  abonusAddress = mappingContract.checkAddress("abonus");
                                  nestToken = ERC20(mappingContract.checkAddress("nest"));                                         
                                  NNcontract = NEST_NodeAssignment(address(mappingContract.checkAddress("nodeAssignment")));      
                                  coderAddress = mappingContract.checkAddress("coder");
                                  dataContract = NEST_3_OfferData(address(mappingContract.checkAddress("offerData")));
                              }
                              
                              /**
                              * @dev Quotation mining
                              * @param ethAmount ETH amount
                              * @param erc20Amount erc20 amount
                              * @param erc20Address erc20Token address
                              */
                              function offer(uint256 ethAmount, uint256 erc20Amount, address erc20Address) public payable {
                                  require(address(msg.sender) == address(tx.origin));
                                  uint256 ethMining = ethAmount.mul(miningETH).div(1000);
                                  require(msg.value == ethAmount.add(ethMining));
                                  require(tokenAllow[erc20Address]);
                                  createOffer(ethAmount,erc20Amount,erc20Address,ethMining);
                                  orePoolLogic.oreDrawing.value(ethMining)(erc20Address);
                              }
                              
                              /**
                              * @dev Generate quote
                              * @param ethAmount ETH amount
                              * @param erc20Amount erc20 amount
                              * @param erc20Address erc20Token address
                              * @param mining Mining Commission
                              */
                              function createOffer(uint256 ethAmount, uint256 erc20Amount, address erc20Address, uint256 mining) private {
                                  require(ethAmount >= leastEth);
                                  require(ethAmount % offerSpan == 0);
                                  require(erc20Amount % (ethAmount.div(offerSpan)) == 0);
                                  ERC20 token = ERC20(erc20Address);
                                  require(token.balanceOf(address(msg.sender)) >= erc20Amount);
                                  require(token.allowance(address(msg.sender), address(this)) >= erc20Amount);
                                  NEST_3_OfferContract newContract = new NEST_3_OfferContract(ethAmount,erc20Amount,erc20Address,mining,address(mappingContract));
                                  dataContract.addContractAddress(address(newContract));
                                  emit offerContractAddress(address(newContract), address(erc20Address), ethAmount, erc20Amount);
                                  token.transferFrom(address(msg.sender), address(newContract), erc20Amount);
                                  newContract.offerAssets.value(ethAmount)();
                                  offerPrice.addPrice(ethAmount,erc20Amount,erc20Address);
                              }
                              
                              /**
                              * @dev Take out quoted assets
                              * @param contractAddress Address of quotation contract
                              */
                              function turnOut(address contractAddress) public {
                                  require(address(msg.sender) == address(tx.origin));
                                  require(dataContract.checkContract(contractAddress));
                                  NEST_3_OfferContract offerContract = NEST_3_OfferContract(contractAddress);
                                  offerContract.turnOut();
                                  uint256 miningEth = offerContract.checkServiceCharge();
                                  uint256 blockNum = offerContract.checkBlockNum();
                                  address tokenAddress = offerContract.checkTokenAddress();
                                  if (miningEth > 0) {
                                      uint256 miningAmount = orePoolLogic.mining(miningEth, blockNum, address(this),tokenAddress);
                                      uint256 coder = miningAmount.mul(coderAmount).div(100);
                                      uint256 NN = miningAmount.mul(NNAmount).div(100);
                                      uint256 other = miningAmount.mul(otherAmount).div(100);
                                      nestToken.transfer(address(tx.origin), other);
                                      require(nestToken.approve(address(NNcontract), NN));
                                      NNcontract.bookKeeping(NN);                                               
                                      nestToken.transfer(coderAddress, coder);
                                  }
                              }
                              
                              /**
                              * @dev Transfer erc20 to buy eth
                              * @param ethAmount Offer ETH amount
                              * @param tokenAmount Offer erc20 amount
                              * @param contractAddress Address of quotation contract
                              * @param tranEthAmount ETH amount of transaction
                              * @param tranTokenAmount erc20 amount of transaction
                              * @param tranTokenAddress erc20Token address
                              */
                              function ethTran(uint256 ethAmount, uint256 tokenAmount, address contractAddress, uint256 tranEthAmount, uint256 tranTokenAmount, address tranTokenAddress) public payable {
                                  require(address(msg.sender) == address(tx.origin));
                                  require(dataContract.checkContract(contractAddress));
                                  require(ethAmount >= tranEthAmount.mul(tranAddition));
                                  uint256 serviceCharge = tranEthAmount.mul(tranEth).div(1000);
                                  require(msg.value == ethAmount.add(tranEthAmount).add(serviceCharge));
                                  require(tranEthAmount % offerSpan == 0);
                                  createOffer(ethAmount,tokenAmount,tranTokenAddress,0);
                                  NEST_3_OfferContract offerContract = NEST_3_OfferContract(contractAddress);
                                  offerContract.changeOfferEth.value(tranEthAmount)(tranTokenAmount, tranTokenAddress);
                                  offerPrice.changePrice(tranEthAmount,tranTokenAmount,tranTokenAddress,offerContract.checkBlockNum());
                                  emit offerTran(address(tx.origin), address(0x0), tranEthAmount,address(tranTokenAddress),tranTokenAmount,contractAddress,offerContract.checkOwner());
                                  repayEth(abonusAddress,serviceCharge);
                              }
                              
                              /**
                              * @dev Transfer eth to buy erc20
                              * @param ethAmount Offer ETH amount
                              * @param tokenAmount Offer erc20 amount
                              * @param contractAddress Address of quotation contract
                              * @param tranEthAmount ETH amount of transaction
                              * @param tranTokenAmount erc20 amount of transaction
                              * @param tranTokenAddress erc20Token address
                              */
                              function ercTran(uint256 ethAmount, uint256 tokenAmount, address contractAddress, uint256 tranEthAmount, uint256 tranTokenAmount, address tranTokenAddress) public payable {
                                  require(address(msg.sender) == address(tx.origin));
                                  require(dataContract.checkContract(contractAddress));
                                  require(ethAmount >= tranEthAmount.mul(tranAddition));
                                  uint256 serviceCharge = tranEthAmount.mul(tranEth).div(1000);
                                  require(msg.value == ethAmount.add(serviceCharge));
                                  require(tranEthAmount % offerSpan == 0);
                                  createOffer(ethAmount,tokenAmount,tranTokenAddress,0);
                                  NEST_3_OfferContract offerContract = NEST_3_OfferContract(contractAddress);
                                  ERC20 token = ERC20(tranTokenAddress);
                                  require(token.balanceOf(address(msg.sender)) >= tranTokenAmount);
                                  require(token.allowance(address(msg.sender), address(this)) >= tranTokenAmount);
                                  token.transferFrom(address(msg.sender), address(offerContract), tranTokenAmount);
                                  offerContract.changeOfferErc(tranEthAmount,tranTokenAmount, tranTokenAddress);
                                  offerPrice.changePrice(tranEthAmount,tranTokenAmount,tranTokenAddress,offerContract.checkBlockNum());
                                  emit offerTran(address(tx.origin),address(tranTokenAddress),tranTokenAmount, address(0x0), tranEthAmount,contractAddress,offerContract.checkOwner());
                                  repayEth(abonusAddress,serviceCharge);
                              }
                              
                              function repayEth(address accountAddress, uint256 asset) private {
                                  address payable addr = accountAddress.make_payable();
                                  addr.transfer(asset);
                              }
                          
                              //  View block interval upper limit
                              function checkBlockLimit() public view returns(uint256) {
                                  return blockLimit;
                              }
                          
                              //  View quotation handling fee
                              function checkMiningETH() public view returns (uint256) {
                                  return miningETH;
                              }
                          
                              //  View transaction charges
                              function checkTranEth() public view returns (uint256) {
                                  return tranEth;
                              }
                          
                              //  View whether token allows mining
                              function checkTokenAllow(address token) public view returns(bool) {
                                  return tokenAllow[token];
                              }
                          
                              //  View transaction bonus
                              function checkTranAddition() public view returns(uint256) {
                                  return tranAddition;
                              }
                          
                              //  View development allocation proportion
                              function checkCoderAmount() public view returns(uint256) {
                                  return coderAmount;
                              }
                          
                              //  View the allocation proportion of guardian nodes
                              function checkNNAmount() public view returns(uint256) {
                                  return NNAmount;
                              }
                          
                              //  View user assignable proportion
                              function checkOtherAmount() public view returns(uint256) {
                                  return otherAmount;
                              }
                          
                              //  View minimum quote eth
                              function checkleastEth() public view returns(uint256) {
                                  return leastEth;
                              }
                          
                              //  View quote eth span
                              function checkOfferSpan() public view returns(uint256) {
                                  return offerSpan;
                              }
                          
                              function changeMiningETH(uint256 num) public onlyOwner {
                                  miningETH = num;
                              }
                          
                              function changeTranEth(uint256 num) public onlyOwner {
                                  tranEth = num;
                              }
                          
                              function changeBlockLimit(uint256 num) public onlyOwner {
                                  blockLimit = num;
                              }
                          
                              function changeTokenAllow(address token, bool allow) public onlyOwner {
                                  tokenAllow[token] = allow;
                              }
                          
                              function changeTranAddition(uint256 num) public onlyOwner {
                                  require(num > 0);
                                  tranAddition = num;
                              }
                          
                              function changeInitialRatio(uint256 coderNum, uint256 NNNum, uint256 otherNum) public onlyOwner {
                                  require(coderNum > 0 && coderNum <= 5);
                                  require(NNNum > 0 && coderNum <= 15);
                                  require(coderNum.add(NNNum).add(otherNum) == 100);
                                  coderAmount = coderNum;
                                  NNAmount = NNNum;
                                  otherAmount = otherNum;
                              }
                          
                              function changeLeastEth(uint256 num) public onlyOwner {
                                  require(num > 0);
                                  leastEth = num;
                              }
                          
                              function changeOfferSpan(uint256 num) public onlyOwner {
                                  require(num > 0);
                                  offerSpan = num;
                              }
                          
                              modifier onlyOwner(){
                                  require(mappingContract.checkOwners(msg.sender) == true);
                                  _;
                              }
                          }
                          
                          
                          /**
                           * @title Quotation contract
                           */
                          contract NEST_3_OfferContract {
                              using SafeMath for uint256;
                              using address_make_payable for address;
                              address owner;                              //  Owner
                              uint256 ethAmount;                          //  ETH amount
                              uint256 tokenAmount;                        //  Token amount
                              address tokenAddress;                       //  Token address
                              uint256 dealEthAmount;                      //  Transaction eth quantity
                              uint256 dealTokenAmount;                    //  Transaction token quantity
                              uint256 blockNum;                           //  This quotation block
                              uint256 serviceCharge;                      //  Service Charge
                              bool hadReceive = false;                    //  Received
                              NEST_2_Mapping mappingContract;             //  Mapping contract
                              NEST_3_OfferFactory offerFactory;           //  Quotation factory
                              
                              /**
                              * @dev initialization
                              * @param _ethAmount Offer ETH amount
                              * @param _tokenAmount Offer erc20 amount
                              * @param _tokenAddress Token address
                              * @param miningEth Service Charge
                              * @param map Mapping contract
                              */
                              constructor (uint256 _ethAmount, uint256 _tokenAmount, address _tokenAddress, uint256 miningEth,address map) public {
                                  mappingContract = NEST_2_Mapping(address(map));
                                  offerFactory = NEST_3_OfferFactory(address(mappingContract.checkAddress("offerFactory")));
                                  require(msg.sender == address(offerFactory));
                                  owner = address(tx.origin);
                                  ethAmount = _ethAmount;
                                  tokenAmount = _tokenAmount;
                                  tokenAddress = _tokenAddress;
                                  dealEthAmount = _ethAmount;
                                  dealTokenAmount = _tokenAmount;
                                  serviceCharge = miningEth;
                                  blockNum = block.number;
                              }
                              
                              function offerAssets() public payable onlyFactory {
                                  require(ERC20(tokenAddress).balanceOf(address(this)) == tokenAmount);
                              }
                              
                              function changeOfferEth(uint256 _tokenAmount, address _tokenAddress) public payable onlyFactory {
                                 require(checkContractState() == 0);
                                 require(dealEthAmount >= msg.value);
                                 require(dealTokenAmount >= _tokenAmount);
                                 require(_tokenAddress == tokenAddress);
                                 require(_tokenAmount == dealTokenAmount.mul(msg.value).div(dealEthAmount));
                                 ERC20(tokenAddress).transfer(address(tx.origin), _tokenAmount);
                                 dealEthAmount = dealEthAmount.sub(msg.value);
                                 dealTokenAmount = dealTokenAmount.sub(_tokenAmount);
                              }
                              
                              function changeOfferErc(uint256 _ethAmount, uint256 _tokenAmount, address _tokenAddress) public onlyFactory {
                                 require(checkContractState() == 0);
                                 require(dealEthAmount >= _ethAmount);
                                 require(dealTokenAmount >= _tokenAmount);
                                 require(_tokenAddress == tokenAddress);
                                 require(_tokenAmount == dealTokenAmount.mul(_ethAmount).div(dealEthAmount));
                                 repayEth(address(tx.origin), _ethAmount);
                                 dealEthAmount = dealEthAmount.sub(_ethAmount);
                                 dealTokenAmount = dealTokenAmount.sub(_tokenAmount);
                              }
                             
                              function repayEth(address accountAddress, uint256 asset) private {
                                  address payable addr = accountAddress.make_payable();
                                  addr.transfer(asset);
                              }
                          
                              function turnOut() public onlyFactory {
                                  require(address(tx.origin) == owner);
                                  require(checkContractState() == 1);
                                  require(hadReceive == false);
                                  uint256 ethAssets;
                                  uint256 tokenAssets;
                                  (ethAssets, tokenAssets,) = checkAssets();
                                  repayEth(owner, ethAssets);
                                  ERC20(address(tokenAddress)).transfer(owner, tokenAssets);
                                  hadReceive = true;
                              }
                              
                              function checkContractState() public view returns (uint256) {
                                  if (block.number.sub(blockNum) > offerFactory.checkBlockLimit()) {
                                      return 1;
                                  }
                                  return 0;
                              }
                          
                              function checkDealAmount() public view returns(uint256 leftEth, uint256 leftErc20, address erc20Address) {
                                  return (dealEthAmount, dealTokenAmount, tokenAddress);
                              }
                          
                              function checkPrice() public view returns(uint256 _ethAmount, uint256 _tokenAmount, address _tokenAddress) {
                                  return (ethAmount, tokenAmount, tokenAddress);
                              }
                          
                              function checkAssets() public view returns(uint256 _ethAmount, uint256 _tokenAmount, address _tokenAddress) {
                                  return (address(this).balance, ERC20(address(tokenAddress)).balanceOf(address(this)), address(tokenAddress));
                              }
                          
                              function checkTokenAddress() public view returns(address){
                                  return tokenAddress;
                              }
                          
                              function checkOwner() public view returns(address) {
                                  return owner;
                              }
                          
                              function checkBlockNum() public view returns (uint256) {
                                  return blockNum;
                              }
                          
                              function checkServiceCharge() public view returns(uint256) {
                                  return serviceCharge;
                              }
                          
                              function checkHadReceive() public view returns(bool) {
                                  return hadReceive;
                              }
                              
                              modifier onlyFactory(){
                                  require(msg.sender == address(offerFactory));
                                  _;
                              }
                          }
                          
                          
                          /**
                           * @title Price contract
                           */
                          contract NEST_2_OfferPrice{
                              using SafeMath for uint256;
                              using address_make_payable for address;
                              NEST_2_Mapping mappingContract;                                 //  Mapping contract
                              NEST_3_OfferFactory offerFactory;                               //  Quotation factory contract
                              struct Price {                                                  //  Price structure
                                  uint256 ethAmount;                                          //  ETH amount
                                  uint256 erc20Amount;                                        //  erc20 amount
                                  uint256 blockNum;                                           //  Last quotation block number, current price block
                              }
                              struct addressPrice {                                           //  Token price information structure
                                  mapping(uint256 => Price) tokenPrice;                       //  Token price, Block number = > price
                                  Price latestPrice;                                          //  Latest price
                              }
                              mapping(address => addressPrice) tokenInfo;                     //  Token price information
                              uint256 priceCost = 0.01 ether;                                 //  Price charge
                              uint256 priceCostUser = 2;                                      //  Price expense user proportion
                              uint256 priceCostAbonus = 8;                                    //  Proportion of price expense dividend pool
                              mapping(uint256 => mapping(address => address)) blockAddress;   //  Last person of block quotation
                              address abonusAddress;                                          //  Dividend pool
                              
                              //  Real time price toekn, ETH quantity, erc20 quantity
                              event nowTokenPrice(address a, uint256 b, uint256 c);
                          
                              /**
                              * @dev Initialization method
                              * @param map Mapping contract address
                              */
                              constructor (address map) public {
                                  mappingContract = NEST_2_Mapping(address(map));
                                  offerFactory = NEST_3_OfferFactory(address(mappingContract.checkAddress("offerFactory")));
                                  abonusAddress = address(mappingContract.checkAddress("abonus"));
                              }
                              
                              /**
                              * @dev Initialization method
                              * @param map Mapping contract address
                              */
                              function changeMapping(address map) public onlyOwner {
                                  mappingContract = NEST_2_Mapping(map);                                                      
                                  offerFactory = NEST_3_OfferFactory(address(mappingContract.checkAddress("offerFactory")));
                                  abonusAddress = address(mappingContract.checkAddress("abonus"));
                              }
                              
                              /**
                              * @dev Increase price
                              * @param _ethAmount ETH amount
                              * @param _tokenAmount Token amount
                              * @param _tokenAddress Token address
                              */
                              function addPrice(uint256 _ethAmount, uint256 _tokenAmount, address _tokenAddress) public onlyFactory {
                                  uint256 blockLimit = offerFactory.checkBlockLimit();                                        
                                  uint256 middleBlock = block.number.sub(blockLimit);                                         
                                  
                                  uint256 priceBlock = tokenInfo[_tokenAddress].latestPrice.blockNum;                         
                                  while(priceBlock >= middleBlock || tokenInfo[_tokenAddress].tokenPrice[priceBlock].ethAmount == 0){                         
                                      priceBlock = tokenInfo[_tokenAddress].tokenPrice[priceBlock].blockNum;
                                      if (priceBlock == 0) {
                                          break;
                                      }
                                  }
                                  tokenInfo[_tokenAddress].latestPrice.ethAmount = tokenInfo[_tokenAddress].tokenPrice[priceBlock].ethAmount;
                                  tokenInfo[_tokenAddress].latestPrice.erc20Amount = tokenInfo[_tokenAddress].tokenPrice[priceBlock].erc20Amount;
                                  tokenInfo[_tokenAddress].tokenPrice[block.number].ethAmount = tokenInfo[_tokenAddress].tokenPrice[block.number].ethAmount.add(_ethAmount);                  //  增加eth数
                                  tokenInfo[_tokenAddress].tokenPrice[block.number].erc20Amount = tokenInfo[_tokenAddress].tokenPrice[block.number].erc20Amount.add(_tokenAmount);            //  增加ercrc20数
                                  if (tokenInfo[_tokenAddress].latestPrice.blockNum != block.number) {
                                      tokenInfo[_tokenAddress].tokenPrice[block.number].blockNum = tokenInfo[_tokenAddress].latestPrice.blockNum;                                                 //  记录上一次报价区块号
                                      tokenInfo[_tokenAddress].latestPrice.blockNum = block.number;                                                                                               //  记录本次报价区块号
                                  }
                          
                                  blockAddress[block.number][_tokenAddress] = address(tx.origin);
                                  
                                  emit nowTokenPrice(_tokenAddress,tokenInfo[_tokenAddress].latestPrice.ethAmount, tokenInfo[_tokenAddress].latestPrice.erc20Amount);
                              }
                              
                              /**
                              * @dev Update price
                              * @param _tokenAddress Token address
                              * @return ethAmount ETH amount
                              * @return erc20Amount Token amount
                              * @return token Token address
                              */
                              function updateAndCheckPriceNow(address _tokenAddress) public payable returns(uint256 ethAmount, uint256 erc20Amount, address token) {
                                  if (msg.sender != tx.origin && msg.sender != address(offerFactory)) {
                                      require(msg.value == priceCost);
                                  }
                                  uint256 blockLimit = offerFactory.checkBlockLimit();                                       
                                  uint256 middleBlock = block.number.sub(blockLimit);                                   
                                  
                                  uint256 priceBlock = tokenInfo[_tokenAddress].latestPrice.blockNum;                     
                                  while(priceBlock >= middleBlock || tokenInfo[_tokenAddress].tokenPrice[priceBlock].ethAmount == 0){                         
                                      priceBlock = tokenInfo[_tokenAddress].tokenPrice[priceBlock].blockNum;
                                      if (priceBlock == 0) {
                                          break;
                                      }
                                  }
                                  tokenInfo[_tokenAddress].latestPrice.ethAmount = tokenInfo[_tokenAddress].tokenPrice[priceBlock].ethAmount;
                                  tokenInfo[_tokenAddress].latestPrice.erc20Amount = tokenInfo[_tokenAddress].tokenPrice[priceBlock].erc20Amount;
                                  if (msg.value > 0) {
                                      repayEth(abonusAddress, msg.value.mul(priceCostAbonus).div(10));
                                      repayEth(blockAddress[priceBlock][_tokenAddress], msg.value.mul(priceCostUser).div(10));
                                  }
                                  return (tokenInfo[_tokenAddress].latestPrice.ethAmount,tokenInfo[_tokenAddress].latestPrice.erc20Amount, _tokenAddress);
                              }
                              
                              function repayEth(address accountAddress, uint256 asset) private {
                                  address payable addr = accountAddress.make_payable();
                                  addr.transfer(asset);
                              }
                              
                              /**
                              * @dev Change price
                              * @param _ethAmount ETH amount
                              * @param _tokenAmount Token amount
                              * @param _tokenAddress Token address
                              * @param blockNum Block number
                              */
                              function changePrice(uint256 _ethAmount, uint256 _tokenAmount, address _tokenAddress, uint256 blockNum) public onlyFactory {
                                  tokenInfo[_tokenAddress].tokenPrice[blockNum].ethAmount = tokenInfo[_tokenAddress].tokenPrice[blockNum].ethAmount.sub(_ethAmount);
                                  tokenInfo[_tokenAddress].tokenPrice[blockNum].erc20Amount = tokenInfo[_tokenAddress].tokenPrice[blockNum].erc20Amount.sub(_tokenAmount);
                              }
                              
                              function checkPriceForBlock(address tokenAddress, uint256 blockNum) public view returns (uint256 ethAmount, uint256 erc20Amount, uint256 frontBlock) {
                                  require(msg.sender == tx.origin);
                                  return (tokenInfo[tokenAddress].tokenPrice[blockNum].ethAmount, tokenInfo[tokenAddress].tokenPrice[blockNum].erc20Amount,tokenInfo[tokenAddress].tokenPrice[blockNum].blockNum);
                              }    
                          
                              function checkPriceNow(address tokenAddress) public view returns (uint256 ethAmount, uint256 erc20Amount,uint256 frontBlock) {
                                  require(msg.sender == tx.origin);
                                  return (tokenInfo[tokenAddress].latestPrice.ethAmount,tokenInfo[tokenAddress].latestPrice.erc20Amount,tokenInfo[tokenAddress].latestPrice.blockNum);
                              }
                          
                              function checkPriceHistoricalAverage(address tokenAddress, uint256 blockNum) public view returns (uint256) {
                                  require(msg.sender == tx.origin);
                                  uint256 blockLimit = offerFactory.checkBlockLimit();                                       
                                  uint256 middleBlock = block.number.sub(blockLimit);                                         
                                  uint256 priceBlock = tokenInfo[tokenAddress].latestPrice.blockNum;                         
                                  while(priceBlock >= middleBlock){                         
                                      priceBlock = tokenInfo[tokenAddress].tokenPrice[priceBlock].blockNum;
                                      if (priceBlock == 0) {
                                          break;
                                      }
                                  }
                                  uint256 frontBlock = priceBlock;
                                  uint256 price = 0;
                                  uint256 priceTimes = 0;
                                  while(frontBlock >= blockNum){   
                                      uint256 erc20Amount = tokenInfo[tokenAddress].tokenPrice[frontBlock].erc20Amount;
                                      uint256 ethAmount = tokenInfo[tokenAddress].tokenPrice[frontBlock].ethAmount;
                                      price = price.add(erc20Amount.mul(1 ether).div(ethAmount));
                                      priceTimes = priceTimes.add(1);
                                      frontBlock = tokenInfo[tokenAddress].tokenPrice[frontBlock].blockNum;
                                      if (frontBlock == 0) {
                                          break;
                                      }
                                  }
                                  return price.div(priceTimes);
                              }
                              
                              function checkPriceForBlockPay(address tokenAddress, uint256 blockNum) public payable returns (uint256 ethAmount, uint256 erc20Amount, uint256 frontBlock) {
                                  require(msg.value == priceCost);
                                  require(tokenInfo[tokenAddress].tokenPrice[blockNum].ethAmount != 0);
                                  repayEth(abonusAddress, msg.value.mul(priceCostAbonus).div(10));
                                  repayEth(blockAddress[blockNum][tokenAddress], msg.value.mul(priceCostUser).div(10));
                                  return (tokenInfo[tokenAddress].tokenPrice[blockNum].ethAmount, tokenInfo[tokenAddress].tokenPrice[blockNum].erc20Amount,tokenInfo[tokenAddress].tokenPrice[blockNum].blockNum);
                              }
                              
                              function checkPriceHistoricalAveragePay(address tokenAddress, uint256 blockNum) public payable returns (uint256) {
                                  require(msg.value == priceCost);
                                  uint256 blockLimit = offerFactory.checkBlockLimit();                                        
                                  uint256 middleBlock = block.number.sub(blockLimit);                                         
                                  uint256 priceBlock = tokenInfo[tokenAddress].latestPrice.blockNum;                          
                                  while(priceBlock >= middleBlock){                         
                                      priceBlock = tokenInfo[tokenAddress].tokenPrice[priceBlock].blockNum;
                                      if (priceBlock == 0) {
                                          break;
                                      }
                                  }
                                  repayEth(abonusAddress, msg.value.mul(priceCostAbonus).div(10));
                                  repayEth(blockAddress[priceBlock][tokenAddress], msg.value.mul(priceCostUser).div(10));
                                  uint256 frontBlock = priceBlock;
                                  uint256 price = 0;
                                  uint256 priceTimes = 0;
                                  while(frontBlock >= blockNum){   
                                      uint256 erc20Amount = tokenInfo[tokenAddress].tokenPrice[frontBlock].erc20Amount;
                                      uint256 ethAmount = tokenInfo[tokenAddress].tokenPrice[frontBlock].ethAmount;
                                      price = price.add(erc20Amount.mul(1 ether).div(ethAmount));
                                      priceTimes = priceTimes.add(1);
                                      frontBlock = tokenInfo[tokenAddress].tokenPrice[frontBlock].blockNum;
                                      if (frontBlock == 0) {
                                          break;
                                      }
                                  }
                                  return price.div(priceTimes);
                              }
                          
                              
                              function checkLatestBlock(address token) public view returns(uint256) {
                                  return tokenInfo[token].latestPrice.blockNum;
                              }
                              
                              function changePriceCost(uint256 amount) public onlyOwner {
                                  require(amount > 0);
                                  priceCost = amount;
                              }
                               
                              function checkPriceCost() public view returns(uint256) {
                                  return priceCost;
                              }
                              
                              function changePriceCostProportion(uint256 user, uint256 abonus) public onlyOwner {
                                  require(user.add(abonus) == 10);
                                  priceCostUser = user;
                                  priceCostAbonus = abonus;
                              }
                              
                              function checkPriceCostProportion() public view returns(uint256 user, uint256 abonus) {
                                  return (priceCostUser, priceCostAbonus);
                              }
                              
                              modifier onlyFactory(){
                                  require(msg.sender == address(mappingContract.checkAddress("offerFactory")));
                                  _;
                              }
                              
                              modifier onlyOwner(){
                                  require(mappingContract.checkOwners(msg.sender) == true);
                                  _;
                              }
                          }
                          
                          contract NEST_NodeAssignment {
                              function bookKeeping(uint256 amount) public;
                          }
                          
                          contract NEST_3_OrePoolLogic {
                              function oreDrawing(address token) public payable;
                              function mining(uint256 amount, uint256 blockNum, address target, address token) public returns(uint256);
                          }
                          
                          contract NEST_2_Mapping {
                              function checkAddress(string memory name) public view returns (address contractAddress);
                              function checkOwners(address man) public view returns (bool);
                          }
                          
                          library address_make_payable {
                             function make_payable(address x) internal pure returns (address payable) {
                                return address(uint160(x));
                             }
                          }
                          
                          contract ERC20 {
                              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;
                              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 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 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 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 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 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_MiningSave
                          pragma solidity ^0.5.8;
                          
                          contract NEST_MiningSave {
                              
                              IBMapping mappingContract;                      
                              ERC20 nestContract;                             
                              
                              constructor (address map) public {
                                  mappingContract = IBMapping(address(map));              
                                  nestContract = ERC20(address(mappingContract.checkAddress("nest")));            
                              }
                              
                              function changeMapping(address map) public onlyOwner {
                                  mappingContract = IBMapping(address(map));              
                                  nestContract = ERC20(address(mappingContract.checkAddress("nest")));            
                              }
                              
                              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("miningCalculation")) == msg.sender);
                                  _;
                              }
                              
                          }
                          
                          
                          contract ERC20 {
                              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);
                          }
                          
                          
                          contract IBMapping {
                          	function checkAddress(string memory name) public view returns (address contractAddress);
                          	function checkOwners(address man) public view returns (bool);
                          }

                          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_3_OrePoolLogic
                          pragma solidity ^0.5.12;
                          
                          /**
                           * @title Mining logic
                           * @dev Calculation of mining quantity
                           */
                          contract NEST_3_OrePoolLogic {
                              using address_make_payable for address;
                              using SafeMath for uint256;
                              uint256 blockAttenuation = 2400000;                         //  Block attenuation interval
                              uint256 attenuationTop = 90;                                //  Attenuation coefficient
                              uint256 attenuationBottom = 100;                            //  Attenuation coefficient
                              mapping(uint256 => mapping(address => uint256)) blockEth;   //  Total service charge of quotation block. block No. = > token address = > total service charge
                              mapping(uint256 => uint256) blockTokenNum;                  //  Block currency quantity. block number = > currency quantity
                              mapping(uint256 => uint256) blockMining;                    //  Ore yield of quotation block. Block No. = > ore yield
                              uint256 latestMining;                                       //  Latest quotation block
                              NEST_2_Mapping mappingContract;                             //  Mapping contract
                              NEST_3_MiningSave miningSave;                               //  Ore pool contract
                              address abonusAddress;                                      //  Address of dividend pool
                              address offerFactoryAddress;                                //  Offer factory contract address
                              mapping(uint256 => uint256) blockAmountList;                //  Attenuation list. block number = > attenuation coefficient
                              uint256 latestBlock;                                        //  Latest attenuation block
                          
                              //  Current block, last quoted block, current block ore yield, current handling fee, token address
                              event oreDrawingLog(uint256 nowBlock, uint256 frontBlock, uint256 blockAmount, uint256 miningEth, address tokenAddress);
                              //  Quotation block, token address, all handling charges of token, my handling charges, number of tokens
                              event miningLog(uint256 blockNum, address tokenAddress, uint256 miningEthAll, uint256 miningEthSelf, uint256 tokenNum);
                          
                              /**
                              * @dev Initialization method
                              * @param map Mapping contract address
                              */
                              constructor(address map) public {
                                  mappingContract = NEST_2_Mapping(address(map));                  
                                  miningSave = NEST_3_MiningSave(mappingContract.checkAddress("miningSave"));
                                  abonusAddress = address(mappingContract.checkAddress("abonus"));
                                  offerFactoryAddress = address(mappingContract.checkAddress("offerFactory"));
                                  latestBlock = block.number.sub(388888);
                                  latestMining = block.number;
                                  blockAmountList[block.number.sub(2788888)] = 400 ether;
                                  blockAmountList[block.number.sub(388888)] = blockAmountList[block.number.sub(2788888)].mul(attenuationTop).div(attenuationBottom);
                              }
                              
                              /**
                              * @dev Change mapping contract
                              * @param map Mapping contract address
                              */
                              function changeMapping(address map) public onlyOwner {
                                  mappingContract = NEST_2_Mapping(address(map));                 
                                  miningSave = NEST_3_MiningSave(mappingContract.checkAddress("miningSave"));
                                  abonusAddress = address(mappingContract.checkAddress("abonus"));
                                  offerFactoryAddress = address(mappingContract.checkAddress("offerFactory"));
                              }
                              
                              /**
                              * @dev Calculation of mining volume
                              * @param token Offer token address
                              */
                              function oreDrawing(address token) public payable {
                                  require(address(msg.sender) == offerFactoryAddress);
                                  uint256 frontBlock = latestMining;
                                  changeBlockAmountList();
                                  if (blockEth[block.number][token] == 0) {
                                      blockTokenNum[block.number] = blockTokenNum[block.number].add(1);
                                  }
                                  blockEth[block.number][token] = blockEth[block.number][token].add(msg.value);
                                  repayEth(msg.value);
                                  emit oreDrawingLog(block.number, frontBlock,blockAmountList[latestBlock],msg.value,token);
                              }
                              
                              /**
                              * @dev Mining
                              * @param amount Number of handling charges
                              * @param blockNum Offer block number
                              * @param target Transfer target
                              * @param token Token address
                              * @return Ore yield
                              */
                              function mining(uint256 amount, uint256 blockNum, address target, address token) public returns(uint256) {
                                  require(address(msg.sender) == offerFactoryAddress);
                                  uint256 miningAmount = amount.mul(blockMining[blockNum]).div(blockEth[blockNum][token].mul(blockTokenNum[blockNum]));
                                  uint256 realAmount = miningSave.turnOut(miningAmount, target);
                                  emit miningLog(blockNum, token,blockEth[blockNum][token],amount,blockTokenNum[blockNum]);
                                  return realAmount;
                              }
                              
                              function changeBlockAmountList() private {
                                  uint256 subBlock = block.number.sub(latestBlock);
                                  if (subBlock >= blockAttenuation) {
                                      uint256 subBlockTimes = subBlock.div(blockAttenuation);
                                      for (uint256 i = 1; i < subBlockTimes.add(1); i++) {
                                          uint256 newBlockAmount = blockAmountList[latestBlock].mul(attenuationTop).div(attenuationBottom);
                                          latestBlock = latestBlock.add(blockAttenuation);
                                          if (latestMining < latestBlock) {
                                              blockMining[block.number] = blockMining[block.number].add((blockAmountList[latestBlock.sub(blockAttenuation)]).mul(latestBlock.sub(latestMining).sub(1)));
                                              latestMining = latestBlock.sub(1);
                                          }
                                          blockAmountList[latestBlock] = newBlockAmount;
                                      }
                                  }
                                  blockMining[block.number] = blockMining[block.number].add(blockAmountList[latestBlock].mul(block.number.sub(latestMining)));
                                  latestMining = block.number;
                              }
                              
                              function repayEth(uint256 asset) private {
                                  address payable addr = abonusAddress.make_payable();
                                  addr.transfer(asset);
                              }
                          
                              //  View block falloff interval
                              function checkBlockAttenuation() public view returns(uint256) {
                                  return blockAttenuation;
                              }
                          
                              //  View attenuation factor
                              function checkAttenuation() public view returns(uint256 top, uint256 bottom) {
                                  return (attenuationTop, attenuationBottom);
                              }
                          
                              //  View the total service charge of quotation block
                              function checkBlockEth(uint256 blockNum, address token) public view returns(uint256) {
                                  return blockEth[blockNum][token];
                              }
                          
                              //  View block currency quantity
                              function checkBlockTokenNum(uint256 blockNum) public view returns(uint256) {
                                  return blockTokenNum[blockNum];
                              }
                          
                              //  View the ore yield of quotation block
                              function checkBlockMining(uint256 blockNum) public view returns(uint256) {
                                  return blockMining[blockNum];
                              }
                          
                              //  View the latest quotation block
                              function checkLatestMining() public view returns(uint256) {
                                  return latestMining;
                              }
                          
                              //  View falloff list
                              function checkBlockAmountList(uint256 blockNum) public view returns(uint256) {
                                  return blockAmountList[blockNum];
                              }
                          
                              //  View current ore output
                              function checkBlockAmountListLatest() public view returns(uint256) {
                                  return blockAmountList[latestBlock];
                              }
                          
                              //  View the latest falloff block
                              function checkLatestBlock() public view returns(uint256) {
                                  return latestBlock;
                              }
                          
                              //  View the output of quotation contract
                              function checkBlockRealAmount(uint256 amount, uint256 blockNum, address token) public view returns(uint256) {
                                  return amount.mul(blockMining[blockNum]).div(blockEth[blockNum][token].mul(blockTokenNum[blockNum]));
                              }
                          
                              function changeBlockAttenuation(uint256 blockNum) public onlyOwner {
                                  require(blockNum > 0);
                                  blockAttenuation = blockNum;
                              }
                              
                              function changeAttenuation(uint256 top, uint256 bottom) public onlyOwner {
                                  require(top > 0);
                                  require(bottom > 0);
                                  attenuationTop = top;
                                  attenuationBottom = bottom;
                              }
                              
                              modifier onlyOwner(){
                                  require(mappingContract.checkOwners(msg.sender) == true);
                                  _;
                              }
                          }
                          
                          contract NEST_3_MiningSave {
                              function turnOut(uint256 amount, address target) public returns(uint256);
                              function checkBalance() public view returns(uint256);
                          }
                          
                          contract NEST_2_Mapping {
                          	function checkAddress(string memory name) public view returns (address contractAddress);
                          	function checkOwners(address man) public view returns (bool);
                          }
                          
                          contract ERC20 {
                              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);
                          }
                          
                          library address_make_payable {
                             function make_payable(address x) internal pure returns (address payable) {
                                return address(uint160(x));
                             }
                          }
                          
                          /**
                           * @title SafeMath
                           * @dev Math operations with safety checks that throw on error
                           */
                          library SafeMath {
                          
                            /**
                            * @dev Multiplies two numbers, throws on overflow.
                            */
                            function mul(uint256 _a, uint256 _b) internal pure returns (uint256 c) {
                              // Gas optimization: this is cheaper than asserting 'a' not being zero, but the
                              // benefit is lost if 'b' is also tested.
                              // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
                              if (_a == 0) {
                                return 0;
                              }
                          
                              c = _a * _b;
                              assert(c / _a == _b);
                              return c;
                            }
                          
                            /**
                            * @dev Integer division of two numbers, truncating the quotient.
                            */
                            function div(uint256 _a, uint256 _b) internal pure returns (uint256) {
                              assert(_b > 0); // Solidity automatically throws when dividing by 0
                              uint256 c = _a / _b;
                              assert(_a == _b * c + _a % _b); // There is no case in which this doesn't hold
                              return _a / _b;
                            }
                          
                            /**
                            * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
                            */
                            function sub(uint256 _a, uint256 _b) internal pure returns (uint256) {
                              assert(_b <= _a);
                              return _a - _b;
                            }
                          
                            /**
                            * @dev Adds two numbers, throws on overflow.
                            */
                            function add(uint256 _a, uint256 _b) internal pure returns (uint256 c) {
                              c = _a + _b;
                              assert(c >= _a);
                              return c;
                            }
                          }

                          File 6 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 7 of 11: NEST_3_OfferData
                          pragma solidity ^0.5.12;
                          
                          /**
                           * @title Quotation data contract
                           * @dev Verification of quotation contract
                           */
                          contract NEST_3_OfferData {
                          
                              mapping (address => bool) addressMapping;       //  Deployed quote contracts
                              NEST_2_Mapping mappingContract;                 //  Mapping contract
                              
                              /**
                              * @dev Initialization method
                              * @param map Mapping contract address
                              */
                              constructor(address map) public{
                                  mappingContract = NEST_2_Mapping(map);                                                      
                              }
                              
                              /**
                              * @dev Initialization method
                              * @param map Mapping contract address
                              */
                              function changeMapping(address map) public onlyOwner {
                                  mappingContract = NEST_2_Mapping(map);                                                    
                              }
                              
                              /**
                              * @dev Initialization method
                              * @param contractAddress Address of quotation contract
                              * @return existence of quotation contract
                              */
                              function checkContract(address contractAddress) public view returns (bool){
                                  require(contractAddress != address(0x0));
                                  return addressMapping[contractAddress];
                              }
                              
                              /**
                              * @dev Add quote contract address
                              * @param contractAddress Address of quotation contract
                              */
                              function addContractAddress(address contractAddress) public {
                                  require(address(mappingContract.checkAddress("offerFactory")) == msg.sender);
                                  addressMapping[contractAddress] = true;
                              }
                              
                              modifier onlyOwner(){
                                  require(mappingContract.checkOwners(msg.sender) == true);
                                  _;
                              }
                          }
                          
                          /**
                           * @title Quotation factory
                           * @dev Quotation mining
                           */
                          contract NEST_3_OfferFactory {
                              using SafeMath for uint256;
                              using address_make_payable for address;
                              mapping(address => bool) tokenAllow;                //  Insured mining token
                              NEST_2_Mapping mappingContract;                     //  Mapping contract
                              NEST_3_OfferData dataContract;                      //  Data contract
                              NEST_2_OfferPrice offerPrice;                       //  Price contract
                              NEST_3_OrePoolLogic orePoolLogic;                   //  Mining contract
                              NEST_NodeAssignment NNcontract;                     //  NestNode contract
                              ERC20 nestToken;                                    //  nestToken
                              address abonusAddress;                              //  Dividend pool
                              address coderAddress;                               //  Developer address
                              uint256 miningETH = 10;                             //  Quotation mining service charge mining proportion, 10 thousandths
                              uint256 tranEth = 2;                                //  Service charge proportion of the bill of lading, 2 ‰
                              uint256 blockLimit = 25;                            //  Block interval upper limit
                              uint256 tranAddition = 2;                           //  Transaction bonus
                              uint256 coderAmount = 5;                            //  Developer ratio
                              uint256 NNAmount = 15;                              //  Guardian node proportion
                              uint256 otherAmount = 80;                           //  Distributable proportion
                              uint256 leastEth = 1 ether;                         //  Minimum offer eth
                              uint256 offerSpan = 1 ether;                        //  Quotation eth span
                              
                              //  log Personal asset contract
                              event offerTokenContractAddress(address contractAddress);    
                              //  log Quotation contract, token address, ETH quantity, erc20 quantity     
                              event offerContractAddress(address contractAddress, address tokenAddress, uint256 ethAmount, uint256 erc20Amount); 
                              //  log Transaction, transaction initiator, transaction token address, transaction token quantity, purchase token address, purchase token quantity, traded quotation 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 map Mapping contract address
                              */
                              constructor (address map) public {
                                  mappingContract = NEST_2_Mapping(map);                                                      
                                  offerPrice = NEST_2_OfferPrice(address(mappingContract.checkAddress("offerPrice")));        
                                  orePoolLogic = NEST_3_OrePoolLogic(address(mappingContract.checkAddress("miningCalculation")));
                                  abonusAddress = mappingContract.checkAddress("abonus");
                                  nestToken = ERC20(mappingContract.checkAddress("nest"));                                        
                                  NNcontract = NEST_NodeAssignment(address(mappingContract.checkAddress("nodeAssignment")));      
                                  coderAddress = mappingContract.checkAddress("coder");
                                  dataContract = NEST_3_OfferData(address(mappingContract.checkAddress("offerData")));
                              }
                              
                              /**
                              * @dev Change mapping contract
                              * @param map Mapping contract address
                              */
                              function changeMapping(address map) public onlyOwner {
                                  mappingContract = NEST_2_Mapping(map);                                                          
                                  offerPrice = NEST_2_OfferPrice(address(mappingContract.checkAddress("offerPrice")));            
                                  orePoolLogic = NEST_3_OrePoolLogic(address(mappingContract.checkAddress("miningCalculation")));
                                  abonusAddress = mappingContract.checkAddress("abonus");
                                  nestToken = ERC20(mappingContract.checkAddress("nest"));                                         
                                  NNcontract = NEST_NodeAssignment(address(mappingContract.checkAddress("nodeAssignment")));      
                                  coderAddress = mappingContract.checkAddress("coder");
                                  dataContract = NEST_3_OfferData(address(mappingContract.checkAddress("offerData")));
                              }
                              
                              /**
                              * @dev Quotation mining
                              * @param ethAmount ETH amount
                              * @param erc20Amount erc20 amount
                              * @param erc20Address erc20Token address
                              */
                              function offer(uint256 ethAmount, uint256 erc20Amount, address erc20Address) public payable {
                                  require(address(msg.sender) == address(tx.origin));
                                  uint256 ethMining = ethAmount.mul(miningETH).div(1000);
                                  require(msg.value == ethAmount.add(ethMining));
                                  require(tokenAllow[erc20Address]);
                                  createOffer(ethAmount,erc20Amount,erc20Address,ethMining);
                                  orePoolLogic.oreDrawing.value(ethMining)(erc20Address);
                              }
                              
                              /**
                              * @dev Generate quote
                              * @param ethAmount ETH amount
                              * @param erc20Amount erc20 amount
                              * @param erc20Address erc20Token address
                              * @param mining Mining Commission
                              */
                              function createOffer(uint256 ethAmount, uint256 erc20Amount, address erc20Address, uint256 mining) private {
                                  require(ethAmount >= leastEth);
                                  require(ethAmount % offerSpan == 0);
                                  require(erc20Amount % (ethAmount.div(offerSpan)) == 0);
                                  ERC20 token = ERC20(erc20Address);
                                  require(token.balanceOf(address(msg.sender)) >= erc20Amount);
                                  require(token.allowance(address(msg.sender), address(this)) >= erc20Amount);
                                  NEST_3_OfferContract newContract = new NEST_3_OfferContract(ethAmount,erc20Amount,erc20Address,mining,address(mappingContract));
                                  dataContract.addContractAddress(address(newContract));
                                  emit offerContractAddress(address(newContract), address(erc20Address), ethAmount, erc20Amount);
                                  token.transferFrom(address(msg.sender), address(newContract), erc20Amount);
                                  newContract.offerAssets.value(ethAmount)();
                                  offerPrice.addPrice(ethAmount,erc20Amount,erc20Address);
                              }
                              
                              /**
                              * @dev Take out quoted assets
                              * @param contractAddress Address of quotation contract
                              */
                              function turnOut(address contractAddress) public {
                                  require(address(msg.sender) == address(tx.origin));
                                  require(dataContract.checkContract(contractAddress));
                                  NEST_3_OfferContract offerContract = NEST_3_OfferContract(contractAddress);
                                  offerContract.turnOut();
                                  uint256 miningEth = offerContract.checkServiceCharge();
                                  uint256 blockNum = offerContract.checkBlockNum();
                                  address tokenAddress = offerContract.checkTokenAddress();
                                  offerPrice.updateAndCheckPriceNow(tokenAddress);
                                  if (miningEth > 0) {
                                      uint256 miningAmount = orePoolLogic.mining(miningEth, blockNum, address(this),tokenAddress);
                                      uint256 coder = miningAmount.mul(coderAmount).div(100);
                                      uint256 NN = miningAmount.mul(NNAmount).div(100);
                                      uint256 other = miningAmount.mul(otherAmount).div(100);
                                      nestToken.transfer(address(tx.origin), other);
                                      require(nestToken.approve(address(NNcontract), NN));
                                      NNcontract.bookKeeping(NN);                                               
                                      nestToken.transfer(coderAddress, coder);
                                  }
                              }
                              
                              /**
                              * @dev Transfer erc20 to buy eth
                              * @param ethAmount Offer ETH amount
                              * @param tokenAmount Offer erc20 amount
                              * @param contractAddress Address of quotation contract
                              * @param tranEthAmount ETH amount of transaction
                              * @param tranTokenAmount erc20 amount of transaction
                              * @param tranTokenAddress erc20Token address
                              */
                              function ethTran(uint256 ethAmount, uint256 tokenAmount, address contractAddress, uint256 tranEthAmount, uint256 tranTokenAmount, address tranTokenAddress) public payable {
                                  require(address(msg.sender) == address(tx.origin));
                                  require(dataContract.checkContract(contractAddress));
                                  require(ethAmount >= tranEthAmount.mul(tranAddition));
                                  uint256 serviceCharge = tranEthAmount.mul(tranEth).div(1000);
                                  require(msg.value == ethAmount.add(tranEthAmount).add(serviceCharge));
                                  require(tranEthAmount % offerSpan == 0);
                                  createOffer(ethAmount,tokenAmount,tranTokenAddress,0);
                                  NEST_3_OfferContract offerContract = NEST_3_OfferContract(contractAddress);
                                  offerContract.changeOfferEth.value(tranEthAmount)(tranTokenAmount, tranTokenAddress);
                                  offerPrice.changePrice(tranEthAmount,tranTokenAmount,tranTokenAddress,offerContract.checkBlockNum());
                                  emit offerTran(address(tx.origin), address(0x0), tranEthAmount,address(tranTokenAddress),tranTokenAmount,contractAddress,offerContract.checkOwner());
                                  repayEth(abonusAddress,serviceCharge);
                              }
                              
                              /**
                              * @dev Transfer eth to buy erc20
                              * @param ethAmount Offer ETH amount
                              * @param tokenAmount Offer erc20 amount
                              * @param contractAddress Address of quotation contract
                              * @param tranEthAmount ETH amount of transaction
                              * @param tranTokenAmount erc20 amount of transaction
                              * @param tranTokenAddress erc20Token address
                              */
                              function ercTran(uint256 ethAmount, uint256 tokenAmount, address contractAddress, uint256 tranEthAmount, uint256 tranTokenAmount, address tranTokenAddress) public payable {
                                  require(address(msg.sender) == address(tx.origin));
                                  require(dataContract.checkContract(contractAddress));
                                  require(ethAmount >= tranEthAmount.mul(tranAddition));
                                  uint256 serviceCharge = tranEthAmount.mul(tranEth).div(1000);
                                  require(msg.value == ethAmount.add(serviceCharge));
                                  require(tranEthAmount % offerSpan == 0);
                                  createOffer(ethAmount,tokenAmount,tranTokenAddress,0);
                                  NEST_3_OfferContract offerContract = NEST_3_OfferContract(contractAddress);
                                  ERC20 token = ERC20(tranTokenAddress);
                                  require(token.balanceOf(address(msg.sender)) >= tranTokenAmount);
                                  require(token.allowance(address(msg.sender), address(this)) >= tranTokenAmount);
                                  token.transferFrom(address(msg.sender), address(offerContract), tranTokenAmount);
                                  offerContract.changeOfferErc(tranEthAmount,tranTokenAmount, tranTokenAddress);
                                  offerPrice.changePrice(tranEthAmount,tranTokenAmount,tranTokenAddress,offerContract.checkBlockNum());
                                  emit offerTran(address(tx.origin),address(tranTokenAddress),tranTokenAmount, address(0x0), tranEthAmount,contractAddress,offerContract.checkOwner());
                                  repayEth(abonusAddress,serviceCharge);
                              }
                              
                              function repayEth(address accountAddress, uint256 asset) private {
                                  address payable addr = accountAddress.make_payable();
                                  addr.transfer(asset);
                              }
                          
                              //  View block interval upper limit
                              function checkBlockLimit() public view returns(uint256) {
                                  return blockLimit;
                              }
                          
                              //  View quotation handling fee
                              function checkMiningETH() public view returns (uint256) {
                                  return miningETH;
                              }
                          
                              //  View transaction charges
                              function checkTranEth() public view returns (uint256) {
                                  return tranEth;
                              }
                          
                              //  View whether token allows mining
                              function checkTokenAllow(address token) public view returns(bool) {
                                  return tokenAllow[token];
                              }
                          
                              //  View transaction bonus
                              function checkTranAddition() public view returns(uint256) {
                                  return tranAddition;
                              }
                          
                              //  View development allocation proportion
                              function checkCoderAmount() public view returns(uint256) {
                                  return coderAmount;
                              }
                          
                              //  View the allocation proportion of guardian nodes
                              function checkNNAmount() public view returns(uint256) {
                                  return NNAmount;
                              }
                          
                              //  View user assignable proportion
                              function checkOtherAmount() public view returns(uint256) {
                                  return otherAmount;
                              }
                          
                              //  View minimum quote eth
                              function checkleastEth() public view returns(uint256) {
                                  return leastEth;
                              }
                          
                              //  View quote eth span
                              function checkOfferSpan() public view returns(uint256) {
                                  return offerSpan;
                              }
                          
                              function changeMiningETH(uint256 num) public onlyOwner {
                                  miningETH = num;
                              }
                          
                              function changeTranEth(uint256 num) public onlyOwner {
                                  tranEth = num;
                              }
                          
                              function changeBlockLimit(uint256 num) public onlyOwner {
                                  blockLimit = num;
                              }
                          
                              function changeTokenAllow(address token, bool allow) public onlyOwner {
                                  tokenAllow[token] = allow;
                              }
                          
                              function changeTranAddition(uint256 num) public onlyOwner {
                                  require(num > 0);
                                  tranAddition = num;
                              }
                          
                              function changeInitialRatio(uint256 coderNum, uint256 NNNum, uint256 otherNum) public onlyOwner {
                                  require(coderNum > 0 && coderNum <= 5);
                                  require(NNNum > 0 && coderNum <= 15);
                                  require(coderNum.add(NNNum).add(otherNum) == 100);
                                  coderAmount = coderNum;
                                  NNAmount = NNNum;
                                  otherAmount = otherNum;
                              }
                          
                              function changeLeastEth(uint256 num) public onlyOwner {
                                  require(num > 0);
                                  leastEth = num;
                              }
                          
                              function changeOfferSpan(uint256 num) public onlyOwner {
                                  require(num > 0);
                                  offerSpan = num;
                              }
                          
                              modifier onlyOwner(){
                                  require(mappingContract.checkOwners(msg.sender) == true);
                                  _;
                              }
                          }
                          
                          
                          /**
                           * @title Quotation contract
                           */
                          contract NEST_3_OfferContract {
                              using SafeMath for uint256;
                              using address_make_payable for address;
                              address owner;                              //  Owner
                              uint256 ethAmount;                          //  ETH amount
                              uint256 tokenAmount;                        //  Token amount
                              address tokenAddress;                       //  Token address
                              uint256 dealEthAmount;                      //  Transaction eth quantity
                              uint256 dealTokenAmount;                    //  Transaction token quantity
                              uint256 blockNum;                           //  This quotation block
                              uint256 serviceCharge;                      //  Service Charge
                              bool hadReceive = false;                    //  Received
                              NEST_2_Mapping mappingContract;             //  Mapping contract
                              NEST_3_OfferFactory offerFactory;           //  Quotation factory
                              
                              /**
                              * @dev initialization
                              * @param _ethAmount Offer ETH amount
                              * @param _tokenAmount Offer erc20 amount
                              * @param _tokenAddress Token address
                              * @param miningEth Service Charge
                              * @param map Mapping contract
                              */
                              constructor (uint256 _ethAmount, uint256 _tokenAmount, address _tokenAddress, uint256 miningEth,address map) public {
                                  mappingContract = NEST_2_Mapping(address(map));
                                  offerFactory = NEST_3_OfferFactory(address(mappingContract.checkAddress("offerFactory")));
                                  require(msg.sender == address(offerFactory));
                                  owner = address(tx.origin);
                                  ethAmount = _ethAmount;
                                  tokenAmount = _tokenAmount;
                                  tokenAddress = _tokenAddress;
                                  dealEthAmount = _ethAmount;
                                  dealTokenAmount = _tokenAmount;
                                  serviceCharge = miningEth;
                                  blockNum = block.number;
                              }
                              
                              function offerAssets() public payable onlyFactory {
                                  require(ERC20(tokenAddress).balanceOf(address(this)) == tokenAmount);
                              }
                              
                              function changeOfferEth(uint256 _tokenAmount, address _tokenAddress) public payable onlyFactory {
                                 require(checkContractState() == 0);
                                 require(dealEthAmount >= msg.value);
                                 require(dealTokenAmount >= _tokenAmount);
                                 require(_tokenAddress == tokenAddress);
                                 require(_tokenAmount == dealTokenAmount.mul(msg.value).div(dealEthAmount));
                                 ERC20(tokenAddress).transfer(address(tx.origin), _tokenAmount);
                                 dealEthAmount = dealEthAmount.sub(msg.value);
                                 dealTokenAmount = dealTokenAmount.sub(_tokenAmount);
                              }
                              
                              function changeOfferErc(uint256 _ethAmount, uint256 _tokenAmount, address _tokenAddress) public onlyFactory {
                                 require(checkContractState() == 0);
                                 require(dealEthAmount >= _ethAmount);
                                 require(dealTokenAmount >= _tokenAmount);
                                 require(_tokenAddress == tokenAddress);
                                 require(_tokenAmount == dealTokenAmount.mul(_ethAmount).div(dealEthAmount));
                                 repayEth(address(tx.origin), _ethAmount);
                                 dealEthAmount = dealEthAmount.sub(_ethAmount);
                                 dealTokenAmount = dealTokenAmount.sub(_tokenAmount);
                              }
                             
                              function repayEth(address accountAddress, uint256 asset) private {
                                  address payable addr = accountAddress.make_payable();
                                  addr.transfer(asset);
                              }
                          
                              function turnOut() public onlyFactory {
                                  require(address(tx.origin) == owner);
                                  require(checkContractState() == 1);
                                  require(hadReceive == false);
                                  uint256 ethAssets;
                                  uint256 tokenAssets;
                                  (ethAssets, tokenAssets,) = checkAssets();
                                  repayEth(owner, ethAssets);
                                  ERC20(address(tokenAddress)).transfer(owner, tokenAssets);
                                  hadReceive = true;
                              }
                              
                              function checkContractState() public view returns (uint256) {
                                  if (block.number.sub(blockNum) > offerFactory.checkBlockLimit()) {
                                      return 1;
                                  }
                                  return 0;
                              }
                          
                              function checkDealAmount() public view returns(uint256 leftEth, uint256 leftErc20, address erc20Address) {
                                  return (dealEthAmount, dealTokenAmount, tokenAddress);
                              }
                          
                              function checkPrice() public view returns(uint256 _ethAmount, uint256 _tokenAmount, address _tokenAddress) {
                                  return (ethAmount, tokenAmount, tokenAddress);
                              }
                          
                              function checkAssets() public view returns(uint256 _ethAmount, uint256 _tokenAmount, address _tokenAddress) {
                                  return (address(this).balance, ERC20(address(tokenAddress)).balanceOf(address(this)), address(tokenAddress));
                              }
                          
                              function checkTokenAddress() public view returns(address){
                                  return tokenAddress;
                              }
                          
                              function checkOwner() public view returns(address) {
                                  return owner;
                              }
                          
                              function checkBlockNum() public view returns (uint256) {
                                  return blockNum;
                              }
                          
                              function checkServiceCharge() public view returns(uint256) {
                                  return serviceCharge;
                              }
                          
                              function checkHadReceive() public view returns(bool) {
                                  return hadReceive;
                              }
                              
                              modifier onlyFactory(){
                                  require(msg.sender == address(offerFactory));
                                  _;
                              }
                          }
                          
                          
                          /**
                           * @title Price contract
                           */
                          contract NEST_2_OfferPrice{
                              using SafeMath for uint256;
                              using address_make_payable for address;
                              NEST_2_Mapping mappingContract;                                 //  Mapping contract
                              NEST_3_OfferFactory offerFactory;                               //  Quotation factory contract
                              struct Price {                                                  //  Price structure
                                  uint256 ethAmount;                                          //  ETH amount
                                  uint256 erc20Amount;                                        //  erc20 amount
                                  uint256 blockNum;                                           //  Last quotation block number, current price block
                              }
                              struct addressPrice {                                           //  Token price information structure
                                  mapping(uint256 => Price) tokenPrice;                       //  Token price, Block number = > price
                                  Price latestPrice;                                          //  Latest price
                              }
                              mapping(address => addressPrice) tokenInfo;                     //  Token price information
                              uint256 priceCost = 0.01 ether;                                 //  Price charge
                              uint256 priceCostUser = 2;                                      //  Price expense user proportion
                              uint256 priceCostAbonus = 8;                                    //  Proportion of price expense dividend pool
                              mapping(uint256 => mapping(address => address)) blockAddress;   //  Last person of block quotation
                              address abonusAddress;                                          //  Dividend pool
                              
                              //  Real time price toekn, ETH quantity, erc20 quantity
                              event nowTokenPrice(address a, uint256 b, uint256 c);
                          
                              /**
                              * @dev Initialization method
                              * @param map Mapping contract address
                              */
                              constructor (address map) public {
                                  mappingContract = NEST_2_Mapping(address(map));
                                  offerFactory = NEST_3_OfferFactory(address(mappingContract.checkAddress("offerFactory")));
                                  abonusAddress = address(mappingContract.checkAddress("abonus"));
                              }
                              
                              /**
                              * @dev Initialization method
                              * @param map Mapping contract address
                              */
                              function changeMapping(address map) public onlyOwner {
                                  mappingContract = NEST_2_Mapping(map);                                                      
                                  offerFactory = NEST_3_OfferFactory(address(mappingContract.checkAddress("offerFactory")));
                                  abonusAddress = address(mappingContract.checkAddress("abonus"));
                              }
                              
                              /**
                              * @dev Increase price
                              * @param _ethAmount ETH amount
                              * @param _tokenAmount Token amount
                              * @param _tokenAddress Token address
                              */
                              function addPrice(uint256 _ethAmount, uint256 _tokenAmount, address _tokenAddress) public onlyFactory {
                                  uint256 blockLimit = offerFactory.checkBlockLimit();                                        
                                  uint256 middleBlock = block.number.sub(blockLimit);                                         
                                  
                                  uint256 priceBlock = tokenInfo[_tokenAddress].latestPrice.blockNum;                         
                                  while(priceBlock >= middleBlock || tokenInfo[_tokenAddress].tokenPrice[priceBlock].ethAmount == 0){                         
                                      priceBlock = tokenInfo[_tokenAddress].tokenPrice[priceBlock].blockNum;
                                      if (priceBlock == 0) {
                                          break;
                                      }
                                  }
                                  tokenInfo[_tokenAddress].latestPrice.ethAmount = tokenInfo[_tokenAddress].tokenPrice[priceBlock].ethAmount;
                                  tokenInfo[_tokenAddress].latestPrice.erc20Amount = tokenInfo[_tokenAddress].tokenPrice[priceBlock].erc20Amount;
                                  tokenInfo[_tokenAddress].tokenPrice[block.number].ethAmount = tokenInfo[_tokenAddress].tokenPrice[block.number].ethAmount.add(_ethAmount);                  //  增加eth数
                                  tokenInfo[_tokenAddress].tokenPrice[block.number].erc20Amount = tokenInfo[_tokenAddress].tokenPrice[block.number].erc20Amount.add(_tokenAmount);            //  增加ercrc20数
                                  if (tokenInfo[_tokenAddress].latestPrice.blockNum != block.number) {
                                      tokenInfo[_tokenAddress].tokenPrice[block.number].blockNum = tokenInfo[_tokenAddress].latestPrice.blockNum;                                                 //  记录上一次报价区块号
                                      tokenInfo[_tokenAddress].latestPrice.blockNum = block.number;                                                                                               //  记录本次报价区块号
                                  }
                          
                                  blockAddress[block.number][_tokenAddress] = address(tx.origin);
                                  
                                  emit nowTokenPrice(_tokenAddress,tokenInfo[_tokenAddress].latestPrice.ethAmount, tokenInfo[_tokenAddress].latestPrice.erc20Amount);
                              }
                              
                              /**
                              * @dev Update price
                              * @param _tokenAddress Token address
                              * @return ethAmount ETH amount
                              * @return erc20Amount Token amount
                              * @return token Token address
                              */
                              function updateAndCheckPriceNow(address _tokenAddress) public payable returns(uint256 ethAmount, uint256 erc20Amount, address token) {
                                  if (msg.sender != tx.origin && msg.sender != address(offerFactory)) {
                                      require(msg.value == priceCost);
                                  }
                                  uint256 blockLimit = offerFactory.checkBlockLimit();                                       
                                  uint256 middleBlock = block.number.sub(blockLimit);                                   
                                  
                                  uint256 priceBlock = tokenInfo[_tokenAddress].latestPrice.blockNum;                     
                                  while(priceBlock >= middleBlock || tokenInfo[_tokenAddress].tokenPrice[priceBlock].ethAmount == 0){                         
                                      priceBlock = tokenInfo[_tokenAddress].tokenPrice[priceBlock].blockNum;
                                      if (priceBlock == 0) {
                                          break;
                                      }
                                  }
                                  tokenInfo[_tokenAddress].latestPrice.ethAmount = tokenInfo[_tokenAddress].tokenPrice[priceBlock].ethAmount;
                                  tokenInfo[_tokenAddress].latestPrice.erc20Amount = tokenInfo[_tokenAddress].tokenPrice[priceBlock].erc20Amount;
                                  if (msg.value > 0) {
                                      repayEth(abonusAddress, msg.value.mul(priceCostAbonus).div(10));
                                      repayEth(blockAddress[priceBlock][_tokenAddress], msg.value.mul(priceCostUser).div(10));
                                  }
                                  return (tokenInfo[_tokenAddress].latestPrice.ethAmount,tokenInfo[_tokenAddress].latestPrice.erc20Amount, _tokenAddress);
                              }
                              
                              function repayEth(address accountAddress, uint256 asset) private {
                                  address payable addr = accountAddress.make_payable();
                                  addr.transfer(asset);
                              }
                              
                              /**
                              * @dev Change price
                              * @param _ethAmount ETH amount
                              * @param _tokenAmount Token amount
                              * @param _tokenAddress Token address
                              * @param blockNum Block number
                              */
                              function changePrice(uint256 _ethAmount, uint256 _tokenAmount, address _tokenAddress, uint256 blockNum) public onlyFactory {
                                  tokenInfo[_tokenAddress].tokenPrice[blockNum].ethAmount = tokenInfo[_tokenAddress].tokenPrice[blockNum].ethAmount.sub(_ethAmount);
                                  tokenInfo[_tokenAddress].tokenPrice[blockNum].erc20Amount = tokenInfo[_tokenAddress].tokenPrice[blockNum].erc20Amount.sub(_tokenAmount);
                              }
                              
                              function checkPriceForBlock(address tokenAddress, uint256 blockNum) public view returns (uint256 ethAmount, uint256 erc20Amount, uint256 frontBlock) {
                                  require(msg.sender == tx.origin);
                                  return (tokenInfo[tokenAddress].tokenPrice[blockNum].ethAmount, tokenInfo[tokenAddress].tokenPrice[blockNum].erc20Amount,tokenInfo[tokenAddress].tokenPrice[blockNum].blockNum);
                              }    
                          
                              function checkPriceNow(address tokenAddress) public view returns (uint256 ethAmount, uint256 erc20Amount,uint256 frontBlock) {
                                  require(msg.sender == tx.origin);
                                  return (tokenInfo[tokenAddress].latestPrice.ethAmount,tokenInfo[tokenAddress].latestPrice.erc20Amount,tokenInfo[tokenAddress].latestPrice.blockNum);
                              }
                          
                              function checkPriceHistoricalAverage(address tokenAddress, uint256 blockNum) public view returns (uint256) {
                                  require(msg.sender == tx.origin);
                                  uint256 blockLimit = offerFactory.checkBlockLimit();                                       
                                  uint256 middleBlock = block.number.sub(blockLimit);                                         
                                  uint256 priceBlock = tokenInfo[tokenAddress].latestPrice.blockNum;                         
                                  while(priceBlock >= middleBlock){                         
                                      priceBlock = tokenInfo[tokenAddress].tokenPrice[priceBlock].blockNum;
                                      if (priceBlock == 0) {
                                          break;
                                      }
                                  }
                                  uint256 frontBlock = priceBlock;
                                  uint256 price = 0;
                                  uint256 priceTimes = 0;
                                  while(frontBlock >= blockNum){   
                                      uint256 erc20Amount = tokenInfo[tokenAddress].tokenPrice[frontBlock].erc20Amount;
                                      uint256 ethAmount = tokenInfo[tokenAddress].tokenPrice[frontBlock].ethAmount;
                                      price = price.add(erc20Amount.mul(1 ether).div(ethAmount));
                                      priceTimes = priceTimes.add(1);
                                      frontBlock = tokenInfo[tokenAddress].tokenPrice[frontBlock].blockNum;
                                      if (frontBlock == 0) {
                                          break;
                                      }
                                  }
                                  return price.div(priceTimes);
                              }
                              
                              function checkPriceForBlockPay(address tokenAddress, uint256 blockNum) public payable returns (uint256 ethAmount, uint256 erc20Amount, uint256 frontBlock) {
                                  require(msg.value == priceCost);
                                  require(tokenInfo[tokenAddress].tokenPrice[blockNum].ethAmount != 0);
                                  repayEth(abonusAddress, msg.value.mul(priceCostAbonus).div(10));
                                  repayEth(blockAddress[blockNum][tokenAddress], msg.value.mul(priceCostUser).div(10));
                                  return (tokenInfo[tokenAddress].tokenPrice[blockNum].ethAmount, tokenInfo[tokenAddress].tokenPrice[blockNum].erc20Amount,tokenInfo[tokenAddress].tokenPrice[blockNum].blockNum);
                              }
                              
                              function checkPriceHistoricalAveragePay(address tokenAddress, uint256 blockNum) public payable returns (uint256) {
                                  require(msg.value == priceCost);
                                  uint256 blockLimit = offerFactory.checkBlockLimit();                                        
                                  uint256 middleBlock = block.number.sub(blockLimit);                                         
                                  uint256 priceBlock = tokenInfo[tokenAddress].latestPrice.blockNum;                          
                                  while(priceBlock >= middleBlock){                         
                                      priceBlock = tokenInfo[tokenAddress].tokenPrice[priceBlock].blockNum;
                                      if (priceBlock == 0) {
                                          break;
                                      }
                                  }
                                  repayEth(abonusAddress, msg.value.mul(priceCostAbonus).div(10));
                                  repayEth(blockAddress[priceBlock][tokenAddress], msg.value.mul(priceCostUser).div(10));
                                  uint256 frontBlock = priceBlock;
                                  uint256 price = 0;
                                  uint256 priceTimes = 0;
                                  while(frontBlock >= blockNum){   
                                      uint256 erc20Amount = tokenInfo[tokenAddress].tokenPrice[frontBlock].erc20Amount;
                                      uint256 ethAmount = tokenInfo[tokenAddress].tokenPrice[frontBlock].ethAmount;
                                      price = price.add(erc20Amount.mul(1 ether).div(ethAmount));
                                      priceTimes = priceTimes.add(1);
                                      frontBlock = tokenInfo[tokenAddress].tokenPrice[frontBlock].blockNum;
                                      if (frontBlock == 0) {
                                          break;
                                      }
                                  }
                                  return price.div(priceTimes);
                              }
                          
                              
                              function checkLatestBlock(address token) public view returns(uint256) {
                                  return tokenInfo[token].latestPrice.blockNum;
                              }
                              
                              function changePriceCost(uint256 amount) public onlyOwner {
                                  require(amount > 0);
                                  priceCost = amount;
                              }
                               
                              function checkPriceCost() public view returns(uint256) {
                                  return priceCost;
                              }
                              
                              function changePriceCostProportion(uint256 user, uint256 abonus) public onlyOwner {
                                  require(user.add(abonus) == 10);
                                  priceCostUser = user;
                                  priceCostAbonus = abonus;
                              }
                              
                              function checkPriceCostProportion() public view returns(uint256 user, uint256 abonus) {
                                  return (priceCostUser, priceCostAbonus);
                              }
                              
                              modifier onlyFactory(){
                                  require(msg.sender == address(mappingContract.checkAddress("offerFactory")));
                                  _;
                              }
                              
                              modifier onlyOwner(){
                                  require(mappingContract.checkOwners(msg.sender) == true);
                                  _;
                              }
                          }
                          
                          contract NEST_NodeAssignment {
                              function bookKeeping(uint256 amount) public;
                          }
                          
                          contract NEST_3_OrePoolLogic {
                              function oreDrawing(address token) public payable;
                              function mining(uint256 amount, uint256 blockNum, address target, address token) public returns(uint256);
                          }
                          
                          contract NEST_2_Mapping {
                              function checkAddress(string memory name) public view returns (address contractAddress);
                              function checkOwners(address man) public view returns (bool);
                          }
                          
                          library address_make_payable {
                             function make_payable(address x) internal pure returns (address payable) {
                                return address(uint160(x));
                             }
                          }
                          
                          contract ERC20 {
                              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;
                              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 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 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 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 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 8 of 11: IBMapping
                          pragma solidity ^0.5.1;
                          
                          /**
                           * @title Mapping contract
                           * @dev Add and delete business contract
                           */
                          contract IBMapping {
                          	mapping(string => address) private ContractAddress;						//	Business contract address
                          	mapping (address => bool) owners;										//	Superman address
                          
                          	/**
                              * @dev Initialization method
                              */
                          	constructor () public {
                          		owners[msg.sender] = true;
                          	}
                          	
                              /**
                              * @dev Inquiry address
                              * @param name String ID
                              * @return contractAddress Contract address
                              */
                          	function checkAddress(string memory name) public view returns (address contractAddress) {
                          		return ContractAddress[name];
                          	}
                          	
                              /**
                              * @dev Add address
                              * @param name String ID
                              * @param contractAddress Contract address
                              */
                          	function addContractAddress(string memory name, address contractAddress) public {
                          		require(checkOwners(msg.sender) == true);
                          		ContractAddress[name] = contractAddress;
                          	}
                          	
                          	/**
                              * @dev Add superman
                              * @param superMan Superman address
                              */
                          	function addSuperMan(address superMan) public {
                          	    require(checkOwners(msg.sender) == true);
                          	    owners[superMan] = true;
                          	}
                          	
                          	/**
                              * @dev Delete superman
                              * @param superMan Superman address
                              */
                          	function deleteSuperMan(address superMan) public {
                          	    require(checkOwners(msg.sender) == true);
                          	    owners[superMan] = false;
                          	}
                          	
                          	/**
                              * @dev Check superman
                              * @param man Superman address
                              * @return Permission or not
                              */
                          	function checkOwners(address man) public view returns (bool){
                          	    return owners[man];
                          	}
                          }

                          File 9 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 10 of 11: NEST_NodeAssignment
                          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 11 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);
                          }