ETH Price: $1,871.36 (-0.36%)

Transaction Decoder

Block:
11590292 at Jan-04-2021 08:54:19 PM +UTC
Transaction Fee:
0.027255231 ETH $51.00
Gas Used:
293,067 Gas / 93 Gwei

Emitted Events:

231 XGoldProxy.0xc33ed40cea88a5a8a40cc428a4c5a17a2b6174dc640a90269fe3dcc60d7735dd( 0xc33ed40cea88a5a8a40cc428a4c5a17a2b6174dc640a90269fe3dcc60d7735dd, 0x000000000000000000000000d72f6bf622047db6add22fe8643ca8872d216c04, 0x000000000000000000000000fd167d5271775aa5848f465425d295819307e3e6, 0000000000000000000000000000000000000000000000000000000000000003, 0000000000000000000000000000000000000000000000000000000000000001 )
232 XGoldProxy.0xc33ed40cea88a5a8a40cc428a4c5a17a2b6174dc640a90269fe3dcc60d7735dd( 0xc33ed40cea88a5a8a40cc428a4c5a17a2b6174dc640a90269fe3dcc60d7735dd, 0x000000000000000000000000d72f6bf622047db6add22fe8643ca8872d216c04, 0x000000000000000000000000824be79c2c9c7de8abce62ed5500233c1fa06230, 0000000000000000000000000000000000000000000000000000000000000003, 0000000000000000000000000000000000000000000000000000000000000003 )
233 XGoldProxy.0xc33ed40cea88a5a8a40cc428a4c5a17a2b6174dc640a90269fe3dcc60d7735dd( 0xc33ed40cea88a5a8a40cc428a4c5a17a2b6174dc640a90269fe3dcc60d7735dd, 0x000000000000000000000000d72f6bf622047db6add22fe8643ca8872d216c04, 0x000000000000000000000000d70fad7bcb578a00a09805f14d2191f874d84bc1, 0000000000000000000000000000000000000000000000000000000000000003, 000000000000000000000000000000000000000000000000000000000000000b )
234 XGoldProxy.0xc33ed40cea88a5a8a40cc428a4c5a17a2b6174dc640a90269fe3dcc60d7735dd( 0xc33ed40cea88a5a8a40cc428a4c5a17a2b6174dc640a90269fe3dcc60d7735dd, 0x000000000000000000000000d72f6bf622047db6add22fe8643ca8872d216c04, 0x000000000000000000000000af9c5ba306de70bc6ef10859dd6af114c094eda7, 0000000000000000000000000000000000000000000000000000000000000003, 000000000000000000000000000000000000000000000000000000000000001b )
235 XGoldProxy.0x7bcc43514e78957cee36184a83aaf0ef8ab3ff9978abc935603fac9d3bb65d7c( 0x7bcc43514e78957cee36184a83aaf0ef8ab3ff9978abc935603fac9d3bb65d7c, 0x000000000000000000000000d72f6bf622047db6add22fe8643ca8872d216c04, 0x000000000000000000000000fd167d5271775aa5848f465425d295819307e3e6, 0000000000000000000000000000000000000000000000000000000000000003 )

Account State Difference:

  Address   Before After State Difference Code
(zhizhu.top)
3,892.864633638066989516 Eth3,892.891888869066989516 Eth0.027255231
0x488e3a4B...7C3dDb6C2
0x824bE79C...c1Fa06230 16.793539633588547591 Eth16.833539633588547591 Eth0.04
0xaf9C5Ba3...4c094EdA7 27.750058939023875161 Eth27.850058939023875161 Eth0.1
0xD70FAD7B...874D84Bc1 0.49535426544018 Eth0.55535426544018 Eth0.06
0xd72f6BF6...72D216C04
0.305787047952960027 Eth
Nonce: 22
0.078531816952960027 Eth
Nonce: 23
0.227255231

Execution Trace

ETH 0.2 XGoldProxy.876cb217( )
  • ETH 0.2 0x7a4a9b21f114126fbfe38969e2a7cbbae4ccadcc.876cb217( )
    • SmartMatrixForsage.users( 0xd72f6BF622047DB6ADd22Fe8643CA8872D216C04 ) => ( id=996303, referrer=0xdC69429a4deda47e2C44F16f67f2553c5Ae1201a, partnersCount=2 )
    • SmartMatrixForsage.users( 0xdC69429a4deda47e2C44F16f67f2553c5Ae1201a ) => ( id=996048, referrer=0xfD167d5271775aA5848F465425D295819307e3E6, partnersCount=1 )
    • ETH 0.04 0x824be79c2c9c7de8abce62ed5500233c1fa06230.CALL( )
    • ETH 0.06 0xd70fad7bcb578a00a09805f14d2191f874d84bc1.CALL( )
    • ETH 0.1 0xaf9c5ba306de70bc6ef10859dd6af114c094eda7.CALL( )
      File 1 of 2: XGoldProxy
      // SPDX-License-Identifier: MIT
      
      pragma solidity ^0.6.0;
      
      /**
       * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
       * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
       * be specified by overriding the virtual {_implementation} function.
       * 
       * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
       * different contract through the {_delegate} function.
       * 
       * The success and return data of the delegated call will be returned back to the caller of the proxy.
       */
      abstract contract Proxy {
          /**
           * @dev Delegates the current call to `implementation`.
           * 
           * This function does not return to its internall call site, it will return directly to the external caller.
           */
          function _delegate(address implementation) internal {
              // solhint-disable-next-line no-inline-assembly
              assembly {
                  // Copy msg.data. We take full control of memory in this inline assembly
                  // block because it will not return to Solidity code. We overwrite the
                  // Solidity scratch pad at memory position 0.
                  calldatacopy(0, 0, calldatasize())
      
                  // Call the implementation.
                  // out and outsize are 0 because we don't know the size yet.
                  let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
      
                  // Copy the returned data.
                  returndatacopy(0, 0, returndatasize())
      
                  switch result
                  // delegatecall returns 0 on error.
                  case 0 { revert(0, returndatasize()) }
                  default { return(0, returndatasize()) }
              }
          }
      
          /**
           * @dev This is a virtual function that should be overriden so it returns the address to which the fallback function
           * and {_fallback} should delegate.
           */
          function _implementation() internal virtual view returns (address);
      
          /**
           * @dev Delegates the current call to the address returned by `_implementation()`.
           * 
           * This function does not return to its internall call site, it will return directly to the external caller.
           */
          function _fallback() internal {
              _beforeFallback();
              _delegate(_implementation());
          }
      
          /**
           * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
           * function in the contract matches the call data.
           */
          fallback () payable external {
              _fallback();
          }
      
          /**
           * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data
           * is empty.
           */
          receive () payable external {
              _fallback();
          }
      
          /**
           * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`
           * call, or as part of the Solidity `fallback` or `receive` functions.
           * 
           * If overriden should call `super._beforeFallback()`.
           */
          function _beforeFallback() internal virtual {
          }
      }
      
      contract XGoldProxy is Proxy {
          
          address public impl;
          address public contractOwner;
      
          address public fourthLevelUpdater;
      
          modifier onlyContractOwner() { 
              require(msg.sender == contractOwner); 
              _; 
          }
      
          constructor(address _impl) public {
              impl = _impl;
              contractOwner = msg.sender;
          }
          
          function update(address newImpl) public onlyContractOwner {
              impl = newImpl;
          }
      
          function removeOwnership() public onlyContractOwner {
              contractOwner = address(0);
          }
          
          function _implementation() internal override view returns (address) {
              return impl;
          }
      }

      File 2 of 2: SmartMatrixForsage
      /**
      *
      *   ,d8888b                                                    
      *   88P'                                                       
      *d888888P                                                      
      *  ?88'     d8888b   88bd88b .d888b, d888b8b   d888b8b   d8888b
      *  88P     d8P' ?88  88P'  ` ?8b,   d8P' ?88  d8P' ?88  d8b_,dP
      * d88      88b  d88 d88        `?8b 88b  ,88b 88b  ,88b 88b    
      *d88'      `?8888P'd88'     `?888P' `?88P'`88b`?88P'`88b`?888P'
      *                                                    )88       
      *                                                   ,88P       
      *                                               `?8888P        
      *
      * 
      * SmartWay Forsage
      * https://forsage.smartway.run
      * (only for SmartWay.run members)
      * 
      **/
      
      
      pragma solidity >=0.4.23 <0.6.0;
      
      contract SmartMatrixForsage {
          
          struct User {
              uint id;
              address referrer;
              uint partnersCount;
              
              mapping(uint8 => bool) activeX3Levels;
              mapping(uint8 => bool) activeX6Levels;
              
              mapping(uint8 => X3) x3Matrix;
              mapping(uint8 => X6) x6Matrix;
          }
          
          struct X3 {
              address currentReferrer;
              address[] referrals;
              bool blocked;
              uint reinvestCount;
          }
          
          struct X6 {
              address currentReferrer;
              address[] firstLevelReferrals;
              address[] secondLevelReferrals;
              bool blocked;
              uint reinvestCount;
      
              address closedPart;
          }
      
          uint8 public constant LAST_LEVEL = 12;
          
          mapping(address => User) public users;
          mapping(uint => address) public idToAddress;
          mapping(uint => address) public userIds;
          mapping(address => uint) public balances; 
      
          uint public lastUserId = 2;
          address public owner;
          
          mapping(uint8 => uint) public levelPrice;
          
          event Registration(address indexed user, address indexed referrer, uint indexed userId, uint referrerId);
          event Reinvest(address indexed user, address indexed currentReferrer, address indexed caller, uint8 matrix, uint8 level);
          event Upgrade(address indexed user, address indexed referrer, uint8 matrix, uint8 level);
          event NewUserPlace(address indexed user, address indexed referrer, uint8 matrix, uint8 level, uint8 place);
          event MissedEthReceive(address indexed receiver, address indexed from, uint8 matrix, uint8 level);
          event SentExtraEthDividends(address indexed from, address indexed receiver, uint8 matrix, uint8 level);
          
          
          constructor(address ownerAddress) public {
              levelPrice[1] = 0.025 ether;
              for (uint8 i = 2; i <= LAST_LEVEL; i++) {
                  levelPrice[i] = levelPrice[i-1] * 2;
              }
              
              owner = ownerAddress;
              
              User memory user = User({
                  id: 1,
                  referrer: address(0),
                  partnersCount: uint(0)
              });
              
              users[ownerAddress] = user;
              idToAddress[1] = ownerAddress;
              
              for (uint8 i = 1; i <= LAST_LEVEL; i++) {
                  users[ownerAddress].activeX3Levels[i] = true;
                  users[ownerAddress].activeX6Levels[i] = true;
              }
              
              userIds[1] = ownerAddress;
          }
          
          function() external payable {
              if(msg.data.length == 0) {
                  return registration(msg.sender, owner);
              }
              
              registration(msg.sender, bytesToAddress(msg.data));
          }
      
          function registrationExt(address referrerAddress) external payable {
              registration(msg.sender, referrerAddress);
          }
          
          function buyNewLevel(uint8 matrix, uint8 level) external payable {
              require(isUserExists(msg.sender), "user is not exists. Register first.");
              require(matrix == 1 || matrix == 2, "invalid matrix");
              require(msg.value == levelPrice[level], "invalid price");
              require(level > 1 && level <= LAST_LEVEL, "invalid level");
      
              if (matrix == 1) {
                  require(!users[msg.sender].activeX3Levels[level], "level already activated");
      
                  if (users[msg.sender].x3Matrix[level-1].blocked) {
                      users[msg.sender].x3Matrix[level-1].blocked = false;
                  }
          
                  address freeX3Referrer = findFreeX3Referrer(msg.sender, level);
                  users[msg.sender].x3Matrix[level].currentReferrer = freeX3Referrer;
                  users[msg.sender].activeX3Levels[level] = true;
                  updateX3Referrer(msg.sender, freeX3Referrer, level);
                  
                  emit Upgrade(msg.sender, freeX3Referrer, 1, level);
      
              } else {
                  require(!users[msg.sender].activeX6Levels[level], "level already activated"); 
      
                  if (users[msg.sender].x6Matrix[level-1].blocked) {
                      users[msg.sender].x6Matrix[level-1].blocked = false;
                  }
      
                  address freeX6Referrer = findFreeX6Referrer(msg.sender, level);
                  
                  users[msg.sender].activeX6Levels[level] = true;
                  updateX6Referrer(msg.sender, freeX6Referrer, level);
                  
                  emit Upgrade(msg.sender, freeX6Referrer, 2, level);
              }
          }    
          
          function registration(address userAddress, address referrerAddress) private {
              require(msg.value == 0.05 ether, "registration cost 0.05");
              require(!isUserExists(userAddress), "user exists");
              require(isUserExists(referrerAddress), "referrer not exists");
              
              uint32 size;
              assembly {
                  size := extcodesize(userAddress)
              }
              require(size == 0, "cannot be a contract");
              
              User memory user = User({
                  id: lastUserId,
                  referrer: referrerAddress,
                  partnersCount: 0
              });
              
              users[userAddress] = user;
              idToAddress[lastUserId] = userAddress;
              
              users[userAddress].referrer = referrerAddress;
              
              users[userAddress].activeX3Levels[1] = true; 
              users[userAddress].activeX6Levels[1] = true;
              
              
              userIds[lastUserId] = userAddress;
              lastUserId++;
              
              users[referrerAddress].partnersCount++;
      
              address freeX3Referrer = findFreeX3Referrer(userAddress, 1);
              users[userAddress].x3Matrix[1].currentReferrer = freeX3Referrer;
              updateX3Referrer(userAddress, freeX3Referrer, 1);
      
              updateX6Referrer(userAddress, findFreeX6Referrer(userAddress, 1), 1);
              
              emit Registration(userAddress, referrerAddress, users[userAddress].id, users[referrerAddress].id);
          }
          
          function updateX3Referrer(address userAddress, address referrerAddress, uint8 level) private {
              users[referrerAddress].x3Matrix[level].referrals.push(userAddress);
      
              if (users[referrerAddress].x3Matrix[level].referrals.length < 3) {
                  emit NewUserPlace(userAddress, referrerAddress, 1, level, uint8(users[referrerAddress].x3Matrix[level].referrals.length));
                  return sendETHDividends(referrerAddress, userAddress, 1, level);
              }
              
              emit NewUserPlace(userAddress, referrerAddress, 1, level, 3);
              //close matrix
              users[referrerAddress].x3Matrix[level].referrals = new address[](0);
              if (!users[referrerAddress].activeX3Levels[level+1] && level != LAST_LEVEL) {
                  users[referrerAddress].x3Matrix[level].blocked = true;
              }
      
              //create new one by recursion
              if (referrerAddress != owner) {
                  //check referrer active level
                  address freeReferrerAddress = findFreeX3Referrer(referrerAddress, level);
                  if (users[referrerAddress].x3Matrix[level].currentReferrer != freeReferrerAddress) {
                      users[referrerAddress].x3Matrix[level].currentReferrer = freeReferrerAddress;
                  }
                  
                  users[referrerAddress].x3Matrix[level].reinvestCount++;
                  emit Reinvest(referrerAddress, freeReferrerAddress, userAddress, 1, level);
                  updateX3Referrer(referrerAddress, freeReferrerAddress, level);
              } else {
                  sendETHDividends(owner, userAddress, 1, level);
                  users[owner].x3Matrix[level].reinvestCount++;
                  emit Reinvest(owner, address(0), userAddress, 1, level);
              }
          }
      
          function updateX6Referrer(address userAddress, address referrerAddress, uint8 level) private {
              require(users[referrerAddress].activeX6Levels[level], "500. Referrer level is inactive");
              
              if (users[referrerAddress].x6Matrix[level].firstLevelReferrals.length < 2) {
                  users[referrerAddress].x6Matrix[level].firstLevelReferrals.push(userAddress);
                  emit NewUserPlace(userAddress, referrerAddress, 2, level, uint8(users[referrerAddress].x6Matrix[level].firstLevelReferrals.length));
                  
                  //set current level
                  users[userAddress].x6Matrix[level].currentReferrer = referrerAddress;
      
                  if (referrerAddress == owner) {
                      return sendETHDividends(referrerAddress, userAddress, 2, level);
                  }
                  
                  address ref = users[referrerAddress].x6Matrix[level].currentReferrer;            
                  users[ref].x6Matrix[level].secondLevelReferrals.push(userAddress); 
                  
                  uint len = users[ref].x6Matrix[level].firstLevelReferrals.length;
                  
                  if ((len == 2) && 
                      (users[ref].x6Matrix[level].firstLevelReferrals[0] == referrerAddress) &&
                      (users[ref].x6Matrix[level].firstLevelReferrals[1] == referrerAddress)) {
                      if (users[referrerAddress].x6Matrix[level].firstLevelReferrals.length == 1) {
                          emit NewUserPlace(userAddress, ref, 2, level, 5);
                      } else {
                          emit NewUserPlace(userAddress, ref, 2, level, 6);
                      }
                  }  else if ((len == 1 || len == 2) &&
                          users[ref].x6Matrix[level].firstLevelReferrals[0] == referrerAddress) {
                      if (users[referrerAddress].x6Matrix[level].firstLevelReferrals.length == 1) {
                          emit NewUserPlace(userAddress, ref, 2, level, 3);
                      } else {
                          emit NewUserPlace(userAddress, ref, 2, level, 4);
                      }
                  } else if (len == 2 && users[ref].x6Matrix[level].firstLevelReferrals[1] == referrerAddress) {
                      if (users[referrerAddress].x6Matrix[level].firstLevelReferrals.length == 1) {
                          emit NewUserPlace(userAddress, ref, 2, level, 5);
                      } else {
                          emit NewUserPlace(userAddress, ref, 2, level, 6);
                      }
                  }
      
                  return updateX6ReferrerSecondLevel(userAddress, ref, level);
              }
              
              users[referrerAddress].x6Matrix[level].secondLevelReferrals.push(userAddress);
      
              if (users[referrerAddress].x6Matrix[level].closedPart != address(0)) {
                  if ((users[referrerAddress].x6Matrix[level].firstLevelReferrals[0] == 
                      users[referrerAddress].x6Matrix[level].firstLevelReferrals[1]) &&
                      (users[referrerAddress].x6Matrix[level].firstLevelReferrals[0] ==
                      users[referrerAddress].x6Matrix[level].closedPart)) {
      
                      updateX6(userAddress, referrerAddress, level, true);
                      return updateX6ReferrerSecondLevel(userAddress, referrerAddress, level);
                  } else if (users[referrerAddress].x6Matrix[level].firstLevelReferrals[0] == 
                      users[referrerAddress].x6Matrix[level].closedPart) {
                      updateX6(userAddress, referrerAddress, level, true);
                      return updateX6ReferrerSecondLevel(userAddress, referrerAddress, level);
                  } else {
                      updateX6(userAddress, referrerAddress, level, false);
                      return updateX6ReferrerSecondLevel(userAddress, referrerAddress, level);
                  }
              }
      
              if (users[referrerAddress].x6Matrix[level].firstLevelReferrals[1] == userAddress) {
                  updateX6(userAddress, referrerAddress, level, false);
                  return updateX6ReferrerSecondLevel(userAddress, referrerAddress, level);
              } else if (users[referrerAddress].x6Matrix[level].firstLevelReferrals[0] == userAddress) {
                  updateX6(userAddress, referrerAddress, level, true);
                  return updateX6ReferrerSecondLevel(userAddress, referrerAddress, level);
              }
              
              if (users[users[referrerAddress].x6Matrix[level].firstLevelReferrals[0]].x6Matrix[level].firstLevelReferrals.length <= 
                  users[users[referrerAddress].x6Matrix[level].firstLevelReferrals[1]].x6Matrix[level].firstLevelReferrals.length) {
                  updateX6(userAddress, referrerAddress, level, false);
              } else {
                  updateX6(userAddress, referrerAddress, level, true);
              }
              
              updateX6ReferrerSecondLevel(userAddress, referrerAddress, level);
          }
      
          function updateX6(address userAddress, address referrerAddress, uint8 level, bool x2) private {
              if (!x2) {
                  users[users[referrerAddress].x6Matrix[level].firstLevelReferrals[0]].x6Matrix[level].firstLevelReferrals.push(userAddress);
                  emit NewUserPlace(userAddress, users[referrerAddress].x6Matrix[level].firstLevelReferrals[0], 2, level, uint8(users[users[referrerAddress].x6Matrix[level].firstLevelReferrals[0]].x6Matrix[level].firstLevelReferrals.length));
                  emit NewUserPlace(userAddress, referrerAddress, 2, level, 2 + uint8(users[users[referrerAddress].x6Matrix[level].firstLevelReferrals[0]].x6Matrix[level].firstLevelReferrals.length));
                  //set current level
                  users[userAddress].x6Matrix[level].currentReferrer = users[referrerAddress].x6Matrix[level].firstLevelReferrals[0];
              } else {
                  users[users[referrerAddress].x6Matrix[level].firstLevelReferrals[1]].x6Matrix[level].firstLevelReferrals.push(userAddress);
                  emit NewUserPlace(userAddress, users[referrerAddress].x6Matrix[level].firstLevelReferrals[1], 2, level, uint8(users[users[referrerAddress].x6Matrix[level].firstLevelReferrals[1]].x6Matrix[level].firstLevelReferrals.length));
                  emit NewUserPlace(userAddress, referrerAddress, 2, level, 4 + uint8(users[users[referrerAddress].x6Matrix[level].firstLevelReferrals[1]].x6Matrix[level].firstLevelReferrals.length));
                  //set current level
                  users[userAddress].x6Matrix[level].currentReferrer = users[referrerAddress].x6Matrix[level].firstLevelReferrals[1];
              }
          }
          
          function updateX6ReferrerSecondLevel(address userAddress, address referrerAddress, uint8 level) private {
              if (users[referrerAddress].x6Matrix[level].secondLevelReferrals.length < 4) {
                  return sendETHDividends(referrerAddress, userAddress, 2, level);
              }
              
              address[] memory x6 = users[users[referrerAddress].x6Matrix[level].currentReferrer].x6Matrix[level].firstLevelReferrals;
              
              if (x6.length == 2) {
                  if (x6[0] == referrerAddress ||
                      x6[1] == referrerAddress) {
                      users[users[referrerAddress].x6Matrix[level].currentReferrer].x6Matrix[level].closedPart = referrerAddress;
                  } else if (x6.length == 1) {
                      if (x6[0] == referrerAddress) {
                          users[users[referrerAddress].x6Matrix[level].currentReferrer].x6Matrix[level].closedPart = referrerAddress;
                      }
                  }
              }
              
              users[referrerAddress].x6Matrix[level].firstLevelReferrals = new address[](0);
              users[referrerAddress].x6Matrix[level].secondLevelReferrals = new address[](0);
              users[referrerAddress].x6Matrix[level].closedPart = address(0);
      
              if (!users[referrerAddress].activeX6Levels[level+1] && level != LAST_LEVEL) {
                  users[referrerAddress].x6Matrix[level].blocked = true;
              }
      
              users[referrerAddress].x6Matrix[level].reinvestCount++;
              
              if (referrerAddress != owner) {
                  address freeReferrerAddress = findFreeX6Referrer(referrerAddress, level);
      
                  emit Reinvest(referrerAddress, freeReferrerAddress, userAddress, 2, level);
                  updateX6Referrer(referrerAddress, freeReferrerAddress, level);
              } else {
                  emit Reinvest(owner, address(0), userAddress, 2, level);
                  sendETHDividends(owner, userAddress, 2, level);
              }
          }
          
          function findFreeX3Referrer(address userAddress, uint8 level) public view returns(address) {
              while (true) {
                  if (users[users[userAddress].referrer].activeX3Levels[level]) {
                      return users[userAddress].referrer;
                  }
                  
                  userAddress = users[userAddress].referrer;
              }
          }
          
          function findFreeX6Referrer(address userAddress, uint8 level) public view returns(address) {
              while (true) {
                  if (users[users[userAddress].referrer].activeX6Levels[level]) {
                      return users[userAddress].referrer;
                  }
                  
                  userAddress = users[userAddress].referrer;
              }
          }
              
          function usersActiveX3Levels(address userAddress, uint8 level) public view returns(bool) {
              return users[userAddress].activeX3Levels[level];
          }
      
          function usersActiveX6Levels(address userAddress, uint8 level) public view returns(bool) {
              return users[userAddress].activeX6Levels[level];
          }
      
          function usersX3Matrix(address userAddress, uint8 level) public view returns(address, address[] memory, bool) {
              return (users[userAddress].x3Matrix[level].currentReferrer,
                      users[userAddress].x3Matrix[level].referrals,
                      users[userAddress].x3Matrix[level].blocked);
          }
      
          function usersX6Matrix(address userAddress, uint8 level) public view returns(address, address[] memory, address[] memory, bool, address) {
              return (users[userAddress].x6Matrix[level].currentReferrer,
                      users[userAddress].x6Matrix[level].firstLevelReferrals,
                      users[userAddress].x6Matrix[level].secondLevelReferrals,
                      users[userAddress].x6Matrix[level].blocked,
                      users[userAddress].x6Matrix[level].closedPart);
          }
          
          function isUserExists(address user) public view returns (bool) {
              return (users[user].id != 0);
          }
      
          function findEthReceiver(address userAddress, address _from, uint8 matrix, uint8 level) private returns(address, bool) {
              address receiver = userAddress;
              bool isExtraDividends;
              if (matrix == 1) {
                  while (true) {
                      if (users[receiver].x3Matrix[level].blocked) {
                          emit MissedEthReceive(receiver, _from, 1, level);
                          isExtraDividends = true;
                          receiver = users[receiver].x3Matrix[level].currentReferrer;
                      } else {
                          return (receiver, isExtraDividends);
                      }
                  }
              } else {
                  while (true) {
                      if (users[receiver].x6Matrix[level].blocked) {
                          emit MissedEthReceive(receiver, _from, 2, level);
                          isExtraDividends = true;
                          receiver = users[receiver].x6Matrix[level].currentReferrer;
                      } else {
                          return (receiver, isExtraDividends);
                      }
                  }
              }
          }
      
          function sendETHDividends(address userAddress, address _from, uint8 matrix, uint8 level) private {
              (address receiver, bool isExtraDividends) = findEthReceiver(userAddress, _from, matrix, level);
      
              if (!address(uint160(receiver)).send(levelPrice[level])) {
                  return address(uint160(receiver)).transfer(address(this).balance);
              }
              
              if (isExtraDividends) {
                  emit SentExtraEthDividends(_from, receiver, matrix, level);
              }
          }
          
          function bytesToAddress(bytes memory bys) private pure returns (address addr) {
              assembly {
                  addr := mload(add(bys, 20))
              }
          }
      }