ETH Price: $2,004.34 (+0.92%)

Transaction Decoder

Block:
7999551 at Jun-21-2019 05:15:54 AM +UTC
Transaction Fee:
0.00267255 ETH $5.36
Gas Used:
534,510 Gas / 5 Gwei

Emitted Events:

34 TokenDAA.Transfer( from=0x0000000000000000000000000000000000000000, to=[Sender] 0x8bd9aec4bbb22c7c6dcf32154c9290a8ef95bd51, value=1090909090 )
35 TokenDAA.Transfer( from=0x0000000000000000000000000000000000000000, to=0x62DCD99F4A4439223e1735F4290f55852E1ab785, value=727272726 )
36 0x7ff7c62260df44a8aaefe4969d416ea6225f447b.0xc2d2a447a971e52248b680f79b47e3a753a51d475e5b34547a59a27ca45376f0( 0xc2d2a447a971e52248b680f79b47e3a753a51d475e5b34547a59a27ca45376f0, 0x000000000000000000000000000000000000000000000000000000000000007c, 0x0000000000000000000000008bd9aec4bbb22c7c6dcf32154c9290a8ef95bd51, 0000000000000000000000000000000000000000000000000c4cf50d1cfcbef1, 000000000000000000000000000000000000000000000000000000000000003c, 0000000000000000000000000000000000000000000000000000000000000001, 0000000000000000000000000000000000000000000000000000000000000023, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000000, 0000000000000000000000000000000000000000000000000000000000000001, 000000000000000000000000000000000000000000000000001550f7dca70000, 0000000000000000000000000000000000000000000000000022fe85d709a000, 0000000000000000000000000000000000000000000000000000000000000000, 000000000000000000000000000000000000000000000000000000005d0c680a )

Account State Difference:

  Address   Before After State Difference Code
0x605d4f10...4BE4B518c
0x7ff7c622...6225f447B
0x8BD9aec4...8Ef95bd51
2.452925315303494937 Eth
Nonce: 205
2.454102765303494937 Eth
Nonce: 206
0.00117745
(HTX: Mining Pool)
55.524753354182573757 Eth55.527425904182573757 Eth0.00267255
0xACe02445...aD71b60B6 0.248338000000000029 Eth0.248428000000000029 Eth0.00009
0xF9b540d1...2f205E523 0.164750658565727973 Eth0.160810658565727973 Eth0.00394

Execution Trace

ETH 0.006 0x7ff7c62260df44a8aaefe4969d416ea6225f447b.cf170217( )
  • Citizen.isCitizen( 0x8BD9aec4bbB22C7C6DCF32154c9290A8Ef95bd51 ) => ( True )
  • ETH 0.006 0x10ad2f8f2e8a576c14dcf0a467d0501843884931.655b08eb( )
  • ETH 0.006 TokenDAA.CALL( )
  • TokenDAA.pushGameRefIncome( _sender=0x8BD9aec4bbB22C7C6DCF32154c9290A8Ef95bd51, _unit=1, _value=90000000000000 )
    • ETH 0.00009 Citizen.pushGametRefIncome( _sender=0x8BD9aec4bbB22C7C6DCF32154c9290A8Ef95bd51 )
    • TokenDAA.payOut( _winner=0x8BD9aec4bbB22C7C6DCF32154c9290A8Ef95bd51, _unit=0, _value=9850000000000000, _valuebet=6000000000000000 )
      • ETH 0.00985 0x8bd9aec4bbb22c7c6dcf32154c9290a8ef95bd51.CALL( )
      • Citizen.addGameEthSpendWin( _citizen=0x8BD9aec4bbB22C7C6DCF32154c9290A8Ef95bd51, _value=6000000000000000, _valuewin=9850000000000000, _enough=True )
        • CitizenStorage.addGameWinIncome( _citizen=0x8BD9aec4bbB22C7C6DCF32154c9290A8Ef95bd51, _value=9850000000000000, _enough=True )
          File 1 of 3: TokenDAA
          pragma solidity >=0.4.22 <0.6.0;
          
          interface tokenRecipient { 
              function receiveApproval(address _from, uint256 _value, address _token, bytes  _extraData) external; 
          }
          
          interface CitizenInterface {
              function pushGametRefIncome(address _sender) external payable;
              function pushGametRefIncomeToken(address _sender, uint256 _amount) external;
              function addGameWinIncome(address _citizen, uint256 _value, bool _enough) external;
              function addGameEthSpendWin(address _citizen, uint256 _value, uint256 _valuewin, bool _enough) external;
          }
          
          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 TokenDAA {
              
              modifier onlyCoreContract() {
                  require(isCoreContract[msg.sender], "admin required");
                  _;
              }
              
              modifier onlyAdmin() {
                  require(msg.sender == devTeam1, "admin required");
                  _;
              }
              
              using SafeMath for *;
              // Public variables of the token
              string public name;
              string public symbol;
              uint8 public decimals = 10;
              uint256 public totalSupply;
              uint256 public totalSupplyBurned;
              uint256 public unitRate;
              // This creates an array with all balances
              mapping (address => uint256) public balanceOf;
              mapping (address => uint256) public totalSupplyByAddress;
              mapping (address => mapping (address => uint256)) public allowance;
              
              // Mining Token
              uint256 public HARD_TOTAL_SUPPLY = 20000000;
              uint256 public HARD_TOTAL_SUPPLY_BY_LEVEL = 200000;
              uint8 public MAX_LEVEL = 9;
              uint8 public MAX_ROUND = 10;
              uint256[10] public ETH_WIN = [uint(55),60,65,70,75,80,85,90,95,100]; // take 3 demical rest is 15
              uint256[10] public ETH_LOSE = [uint(50),55,60,65,70,75,80,85,90,95]; // take 3 demical rest is 15
              uint8 public currentRound = 1;
              uint8 public currentLevel = 0;
              mapping (uint256 => mapping(uint256 =>uint256)) public totalSupplyByLevel;
          
              // Event
              event Transfer(address indexed from, address indexed to, uint256 value);
              event Approval(address indexed _owner, address indexed _spender, uint256 _value);
              event Burn(address indexed from, uint256 value, uint256 creationDate);
              
              // Contract
              mapping (address => bool) public isCoreContract;
              uint256 public coreContractSum;
              address[] public coreContracts;
              CitizenInterface CitizenContract;
              address devTeam1;
              address devTeam2;
              address devTeam3;
              address devTeam4;
              
              // Freeze Tokens
              uint256 LIMIT_FREEZE_TOKEN = 10;
           
          
              struct Profile{
                  uint256 citizenBalanceToken;
                  uint256 citizenBalanceEth;
                  mapping(uint256=>uint256) citizenFrozenBalance;
                  uint256 lastDividendPulledRound;
              }
          
              uint256 public currentRoundDividend=1;
              struct DividendRound{
                  uint256 totalEth;
                  uint256 totalEthCredit;
                  uint256 totalToken;
                  uint256 totalTokenCredit;
                  uint256 totalFrozenBalance;
                  uint256 endRoundTime;
              }
              uint8 public BURN_TOKEN_PERCENT = 50;
              uint8 public DIVIDEND_FOR_CURRENT_PERCENT = 70;
              uint8 public DIVIDEND_KEEP_NEXT_PERCENT = 30;
              uint256 public NEXT_DEVIDEND_ROUND= 1209600; // 2 week = 1209600 seconds
              uint256 public clockDevidend;
              
              mapping (uint256 => DividendRound) public dividendRound;
              mapping (address => Profile) public citizen;
              
          
              /**
               * Constructor function
               *
               * Initializes contract with initial supply tokens to the creator of the contract
               */
               
              constructor(address[4] _devTeam) public {
                  // totalSupply = initialSupply * 10 ** uint256(decimals);  // Update total supply with the decimal amount
                  totalSupply = 0;
                  unitRate = 10 ** uint256(decimals);
                  HARD_TOTAL_SUPPLY = HARD_TOTAL_SUPPLY.mul(unitRate);
                  HARD_TOTAL_SUPPLY_BY_LEVEL = HARD_TOTAL_SUPPLY_BY_LEVEL.mul(unitRate);
                  LIMIT_FREEZE_TOKEN = LIMIT_FREEZE_TOKEN.mul(unitRate);
                  
                  for (uint i = 0; i < ETH_WIN.length; i++){
                      ETH_WIN[i] = ETH_WIN[i].mul(10 ** uint256(15));
                      ETH_LOSE[i]= ETH_LOSE[i].mul(10 ** uint256(15));
                  }
                  balanceOf[msg.sender] = totalSupply;                // Give the creator all initial tokens
                  name = "DABANKING";                                   // Set the name for display purposes
                  symbol = "DAA";                               // Set the symbol for display purposes
                  clockDevidend = 1561899600;
                  
                  devTeam1 = _devTeam[0];
                  devTeam2 = _devTeam[1];
                  devTeam3 = _devTeam[2];
                  devTeam4 = _devTeam[3];
              }
              
          
              // DAAContract, TicketContract, CitizenContract 
              function joinNetwork(address[3] _contract)
                  public
              {
                  require(address(CitizenContract) == 0x0,"already setup");
                  CitizenContract = CitizenInterface(_contract[2]);
                  for(uint256 i =0; i<3; i++){
                      isCoreContract[_contract[i]]=true;
                      coreContracts.push(_contract[i]);
                  }
                  coreContractSum = 3;
              }
              
              function changeDev4(address _address) public onlyAdmin(){
                  require(_address!=0x0,"Invalid address");
                  devTeam4 = _address;
              }
          
              function addCoreContract(address _address) public  // [dev1]
                  onlyAdmin()
              {
                  require(_address!=0x0,"Invalid address");
                  isCoreContract[_address] = true;
                  coreContracts.push(_address);
                  coreContractSum+=1;
              }
              
              function balanceOf(address _sender) public view returns(uint256) {
                  return balanceOf[_sender] - citizen[_sender].citizenFrozenBalance[currentRoundDividend];
              }  
              
              function getBalanceOf(address _sender) public view returns(uint256) {
                  return balanceOf[_sender] - citizen[_sender].citizenFrozenBalance[currentRoundDividend];
              } 
          
              /**
               * Internal transfer, only can be called by this contract
               */
              function _transfer(address _from, address _to, uint _value) internal {
                  // Prevent transfer to 0x0 address. Use burn() instead
                  require(_to != address(0x0));
                  // Check if the sender has enough
                  require(getBalanceOf(_from) >= _value);
                  // Check for overflows
                  require(balanceOf[_to] + _value >= balanceOf[_to]);
                  // Save this for an assertion in the future
                  uint previousBalances = balanceOf[_from] + balanceOf[_to];
                  // Subtract from the sender
                  balanceOf[_from] -= _value;
                  // Add the same to the recipient
                  balanceOf[_to] += _value;
                  if (_to == address(this)){
                      citizen[msg.sender].citizenBalanceToken += _value;
                  }
          
                  emit Transfer(_from, _to, _value);
                  // Asserts are used to use static analysis to find bugs in your code. They should never fail
                  assert(balanceOf[_from] + balanceOf[_to] == previousBalances);
              }
          
              function citizenFreeze(uint _value) public returns (bool success) {
                  require(balanceOf[msg.sender]-citizen[msg.sender].citizenFrozenBalance[currentRoundDividend]>= _value);
                  require(citizen[msg.sender].citizenFrozenBalance[currentRoundDividend] + _value >= LIMIT_FREEZE_TOKEN,"Must over than limit");
                  citizen[msg.sender].citizenFrozenBalance[currentRoundDividend] += _value;
                  dividendRound[currentRoundDividend].totalFrozenBalance += _value;
                  return true;
              }
              
              function citizenUnfreeze() public returns (bool success) {
                  require(citizen[msg.sender].citizenFrozenBalance[currentRoundDividend]>0);
                  dividendRound[currentRoundDividend].totalFrozenBalance -= citizen[msg.sender].citizenFrozenBalance[currentRoundDividend];
                  citizen[msg.sender].citizenFrozenBalance[currentRoundDividend]=0;
                  return true;
              }
              
              function getCitizenFreezing(address _sender) public view returns(uint256){
                  return citizen[_sender].citizenFrozenBalance[currentRoundDividend];
              }    
              
              function getCitizenFreezingBuyRound(address _sender, uint256 _round) public view returns(uint256){
                  return citizen[_sender].citizenFrozenBalance[_round];
              } 
              
              function getCitizenDevidendBuyRound(address _sender, uint256 _round) public view returns(uint256){
                  uint256 _totalEth = dividendRound[_round].totalEth;
                  if (dividendRound[_round].totalEthCredit==0&&dividendRound[_round].totalFrozenBalance>0){
                      return _totalEth*citizen[_sender].citizenFrozenBalance[_round]/dividendRound[_round].totalFrozenBalance;
                  }
                  return 0;
              }
              
              function getDividendView(address _sender) public view returns(uint256){
                  uint256 _last_round = citizen[_sender].lastDividendPulledRound;
                  if (_last_round + 100 < currentRoundDividend) _last_round = currentRoundDividend - 100;
                  uint256 _sum;
                  uint256 _citizen_fronzen;
                  uint256 _totalEth;
                  for (uint256 i = _last_round;i<currentRoundDividend;i++){
                      _totalEth = dividendRound[i].totalEth;
                      if (dividendRound[i].totalEthCredit==0&&dividendRound[i].totalFrozenBalance>0){
                          _citizen_fronzen = citizen[_sender].citizenFrozenBalance[i];
                          _sum = _sum.add(_totalEth.mul(_citizen_fronzen).div(dividendRound[i].totalFrozenBalance));
                      }
                  }
                  return _sum;
              }
              
              function getDividendPull(address _sender, uint256 _value) public returns(uint256){
                  uint256 _last_round = citizen[_sender].lastDividendPulledRound;
                  if (_last_round + 100 < currentRoundDividend) _last_round = currentRoundDividend - 100;
                  uint256 _sum;
                  uint256 _citizen_fronzen;
                  uint256 _totalEth;
                  for (uint256 i = _last_round;i<currentRoundDividend;i++){
                      _totalEth = dividendRound[i].totalEth;
                      if (dividendRound[i].totalEthCredit==0&&dividendRound[i].totalFrozenBalance>0){
                          _citizen_fronzen = citizen[_sender].citizenFrozenBalance[i];
                          _sum = _sum.add(_totalEth.mul(_citizen_fronzen).div(dividendRound[i].totalFrozenBalance));
                      }
                  }
                  if (_value.add(_sum)==0){
                      require(dividendRound[currentRoundDividend].totalEthCredit==0);   
                  }
                  if (citizen[_sender].citizenBalanceEth>0&&dividendRound[currentRoundDividend].totalEthCredit==0){
                      _sum = _sum.add(citizen[_sender].citizenBalanceEth);
                      citizen[_sender].citizenBalanceEth = 0;
                  }
                  _sender.transfer(_sum);
                  citizen[_sender].lastDividendPulledRound = currentRoundDividend;
                  return _sum;
              }
              
              // automatic after 2 share 70% weeks keep 30% next round [dev4]
              function endDividendRound() public {
                  require(msg.sender==devTeam4);
                  require(now>clockDevidend);
                  dividendRound[currentRoundDividend].endRoundTime = now;
                  uint256 _for_next_round;
                  if (dividendRound[currentRoundDividend].totalEthCredit>0){
                      // mean totalEth is <0
                      _for_next_round = dividendRound[currentRoundDividend].totalEth;
                     dividendRound[currentRoundDividend+1].totalEth = _for_next_round;
                     dividendRound[currentRoundDividend+1].totalEthCredit = dividendRound[currentRoundDividend].totalEthCredit;
                  }
                  else{
                      _for_next_round = dividendRound[currentRoundDividend].totalEth*DIVIDEND_KEEP_NEXT_PERCENT/100;
                      dividendRound[currentRoundDividend].totalEth = dividendRound[currentRoundDividend].totalEth*DIVIDEND_FOR_CURRENT_PERCENT/100;
                      dividendRound[currentRoundDividend+1].totalEth = _for_next_round;
                  }
                  if (dividendRound[currentRoundDividend].totalTokenCredit>0){
                      dividendRound[currentRoundDividend+1].totalToken = dividendRound[currentRoundDividend].totalToken;
                      dividendRound[currentRoundDividend+1].totalTokenCredit = dividendRound[currentRoundDividend].totalTokenCredit;
                  }
                  else{
                      // Burn 50% token
                      _for_next_round = dividendRound[currentRoundDividend].totalToken*BURN_TOKEN_PERCENT/100;
                      dividendRound[currentRoundDividend+1].totalToken = _for_next_round;
                      burnFrom(address(this),_for_next_round);
                      burnFrom(devTeam2,_for_next_round*4/6);
                      // balanceOf[address(this)] = balanceOf[address(this)].sub(_for_next_round);
                      // balanceOf[devTeam2] = balanceOf[devTeam2].sub();
                      // totalSupply = totalSupply.sub(_for_next_round*10/6);
                  }
                  currentRoundDividend+=1;
                  clockDevidend= clockDevidend.add(NEXT_DEVIDEND_ROUND);
              }
              
              // share 100% dividen [dev 1]
              function nextDividendRound() onlyAdmin() public {
                  require(dividendRound[currentRoundDividend].totalEth>0);
                  dividendRound[currentRoundDividend].endRoundTime = now;
                  currentRoundDividend+=1;
                  // clockDevidend = clockDevidend.add(NEXT_DEVIDEND_ROUND);
              }
              
              
              function citizenDeposit(uint _value) public returns (bool success) {
                  require(getBalanceOf(msg.sender)>=_value);
                  _transfer(msg.sender, address(this), _value);
                  return true;
              }
              
              function citizenUseDeposit(address _citizen, uint _value) onlyCoreContract() public{
                  require(citizen[_citizen].citizenBalanceToken >= _value,"Not enough Token");
                  dividendRound[currentRoundDividend].totalToken += _value;
                  if (dividendRound[currentRoundDividend].totalToken>dividendRound[currentRoundDividend].totalTokenCredit&&dividendRound[currentRoundDividend].totalTokenCredit>0){
                      dividendRound[currentRoundDividend].totalToken = dividendRound[currentRoundDividend].totalToken.sub(dividendRound[currentRoundDividend].totalTokenCredit);
                      dividendRound[currentRoundDividend].totalTokenCredit=0;
                  }
                  citizen[_citizen].citizenBalanceToken-=_value;
              }
              
              function pushDividend() public payable{
                  uint256 _value = msg.value;
                  dividendRound[currentRoundDividend].totalEth = dividendRound[currentRoundDividend].totalEth.add(_value);
                  if (dividendRound[currentRoundDividend].totalEth>dividendRound[currentRoundDividend].totalEthCredit&&dividendRound[currentRoundDividend].totalEthCredit>0){
                      dividendRound[currentRoundDividend].totalEth = dividendRound[currentRoundDividend].totalEth.sub(dividendRound[currentRoundDividend].totalEthCredit);
                      dividendRound[currentRoundDividend].totalEthCredit=0;
                  }
              }
              
              function payOut(address _winner, uint256 _unit, uint256 _value, uint256 _valuebet) onlyCoreContract() public{
                  if (_unit==0){
                      citizenMintToken(_winner,_valuebet,1);
                      if (dividendRound[currentRoundDividend].totalEth<_value){
                          // ghi no citizen 
                          citizen[_winner].citizenBalanceEth+=_value;
                          CitizenContract.addGameEthSpendWin(_winner, _valuebet, _value, false);
                          dividendRound[currentRoundDividend].totalEthCredit+=_value;
                      }
                      else{
                          _winner.transfer(_value);
                          CitizenContract.addGameEthSpendWin(_winner, _valuebet, _value, true);
                          dividendRound[currentRoundDividend].totalEth = dividendRound[currentRoundDividend].totalEth.sub(_value);
                      }
                  }
                  else{
                      if (dividendRound[currentRoundDividend].totalToken<_value){
                          dividendRound[currentRoundDividend].totalTokenCredit += _value;
                          citizen[_winner].citizenBalanceToken+=_value;
                      }
                      else {
                          dividendRound[currentRoundDividend].totalToken -= _value;
                          citizen[_winner].citizenBalanceToken+=_value;
                      }
                  }
              }
              
              // Tomorrow
              function pushGameRefIncome(address _sender,uint256 _unit, uint256 _value) public onlyCoreContract(){
                  if (_unit==1){
                      dividendRound[currentRoundDividend].totalEth = dividendRound[currentRoundDividend].totalEth.sub(_value);
                      CitizenContract.pushGametRefIncome.value(_value)(_sender);
                  }else{
                      CitizenContract.pushGametRefIncomeToken(_sender,_value);
                  }
                  
              }
          
              function citizenWithdrawDeposit(uint _value) public returns (bool success){
                  require(citizen[msg.sender].citizenBalanceToken >=_value);
                  _transfer(address(this),msg.sender,_value);
                  citizen[msg.sender].citizenBalanceToken-=_value;
                  return true;
              }
              
              function ethToToken(uint256 _ethAmount, int8 _is_win) private view returns(uint256){
                  if (_is_win==1) {
                      return uint256(_ethAmount) * unitRate / uint256(ETH_WIN[currentLevel]);}
                  return _ethAmount * unitRate / uint256(ETH_LOSE[currentLevel]) ;
              }    
          
              function citizenMintToken(address _buyer, uint256 _buyPrice, int8 _is_win) public onlyCoreContract() returns(uint256) {
                  uint256 revTokens = ethToToken( _buyPrice, _is_win);
          
                  if (revTokens*10/6 + totalSupplyByLevel[currentRound][currentLevel] > HARD_TOTAL_SUPPLY_BY_LEVEL){
                      uint256 revTokenCurrentLevel = HARD_TOTAL_SUPPLY_BY_LEVEL.sub(totalSupplyByLevel[currentRound][currentLevel]);
                      revTokenCurrentLevel = revTokenCurrentLevel*6/10;
                      balanceOf[_buyer]= balanceOf[_buyer].add(revTokenCurrentLevel);
                      emit Transfer(0x0, _buyer, revTokenCurrentLevel);
                      totalSupplyByAddress[_buyer] = totalSupplyByAddress[_buyer].add(revTokenCurrentLevel);
                      balanceOf[devTeam2] = balanceOf[devTeam2].add(revTokenCurrentLevel*4/6);
                      emit Transfer(0x0, devTeam2, revTokenCurrentLevel*4/6);
                      
                      totalSupply = totalSupply.add(revTokenCurrentLevel*10/6);
                      totalSupplyByLevel[currentRound][currentLevel] = HARD_TOTAL_SUPPLY_BY_LEVEL;
                      
                      // End round uplevel
                      if (currentLevel+1>MAX_LEVEL){
                          if(currentRound+1>MAX_ROUND){
                              return revTokenCurrentLevel;
                          }
                          currentRound+=1;
                          currentLevel=0;
                      } else {
                          currentLevel+=1;
                      }
                      
                      // Push pushDividend change to each 2 weeks
                      return revTokenCurrentLevel;
                  } else {
                      balanceOf[_buyer]= balanceOf[_buyer].add(revTokens);
                      emit Transfer(0x0, _buyer, revTokens);
                      totalSupplyByAddress[_buyer] = totalSupplyByAddress[_buyer].add(revTokens);
                      balanceOf[devTeam2] = balanceOf[devTeam2].add(revTokens*4/6);
                      emit Transfer(0x0, devTeam2, revTokens*4/6);
                      
                      totalSupply = totalSupply.add(revTokens*10/6);
                      totalSupplyByLevel[currentRound][currentLevel] = totalSupplyByLevel[currentRound][currentLevel].add(revTokens*10/6);
                      return revTokens;
                  }
              }
              
              function getCitizenBalanceEth(address _sender) view public returns(uint256){
                  return citizen[_sender].citizenBalanceEth;
              } 
          
              /**
               * Transfer tokens
               *
               * Send `_value` tokens to `_to` from your account
               *
               * @param _to The address of the recipient
               * @param _value the amount to send
               */
              function transfer(address _to, uint256 _value) public returns (bool success) {
                  _transfer(msg.sender, _to, _value);
                  return true;
              }
          
              /**
               * Transfer tokens from other address
               *
               * Send `_value` tokens to `_to` on behalf of `_from`
               *
               * @param _from The address of the sender
               * @param _to The address of the recipient
               * @param _value the amount to send
               */
              function transferFrom(address _from, address _to, uint256 _value) public returns (bool success) {
                  require(_value <= allowance[_from][msg.sender]);     // Check allowance
                  allowance[_from][msg.sender] -= _value;
                  _transfer(_from, _to, _value);
                  return true;
              }
          
              /**
               * Set allowance for other address
               *
               * Allows `_spender` to spend no more than `_value` tokens on your behalf
               *
               * @param _spender The address authorized to spend
               * @param _value the max amount they can spend
               */
              function approve(address _spender, uint256 _value) public
                  returns (bool success) {
                  allowance[msg.sender][_spender] = _value;
                  // emit Approval(msg.sender, _spender, _value);
                  return true;
              }
          
              /**
               * Set allowance for other address and notify
               *
               * Allows `_spender` to spend no more than `_value` tokens on your behalf, and then ping the contract about it
               *
               * @param _spender The address authorized to spend
               * @param _value the max amount they can spend
               * @param _extraData some extra information to send to the approved contract
               */
              function approveAndCall(address _spender, uint256 _value, bytes _extraData)
                  public
                  returns (bool success) {
                  tokenRecipient spender = tokenRecipient(_spender);
                  if (approve(_spender, _value)) {
                      spender.receiveApproval(msg.sender, _value, address(this), _extraData);
                      return true;
                  }
              }
          
              /**
               * Destroy tokens
               *
               * Remove `_value` tokens from the system irreversibly
               *
               * @param _value the amount of money to burn
               */
              function burn(uint256 _value) public returns (bool success) {
                  require(balanceOf[msg.sender] >= _value);   // Check if the sender has enough
                  balanceOf[msg.sender] -= _value;            // Subtract from the sender
                  totalSupply -= _value;                      // Updates totalSupply
                  emit Burn(msg.sender, _value, now);
                  return true;
              }
          
              /**
               * Destroy tokens from other account
               *
               * Remove `_value` tokens from the system irreversibly on behalf of `_from`.
               *
               * @param _from the address of the sender
               * @param _value the amount of money to burn
               */
              function burnFrom(address _from, uint256 _value) public returns (bool success) {
                  require(balanceOf[_from] >= _value);                // Check if the targeted balance is enough
                  // require(_value <= allowance[_from][msg.sender]);    // Check allowance
                  balanceOf[_from] -= _value;                         // Subtract from the targeted balance
                  // allowance[_from][msg.sender] -= _value;             // Subtract from the sender's allowance
                  totalSupply -= _value;                              // Update totalSupply
                  totalSupplyBurned += _value;
                  emit Burn(_from, _value, now);
                  return true;
              }
          }

          File 2 of 3: Citizen
          pragma solidity ^0.4.24;
          // pragma experimental ABIEncoderV2;
          /**
           * @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;
              }
          }
          
          
          library Helper {
              using SafeMath for uint256;
              
                  
              function bytes32ToUint(bytes32 n) 
                  public
                  pure
                  returns (uint256) 
              {
                  return uint256(n);
              }
              
              function stringToBytes32(string memory source) 
                  public
                  pure
                  returns (bytes32 result) 
              {
                  bytes memory tempEmptyStringTest = bytes(source);
                  if (tempEmptyStringTest.length == 0) {
                      return 0x0;
                  }
          
                  assembly {
                      result := mload(add(source, 32))
                  }
              }
              
              function stringToUint(string memory source) 
                  public
                  pure
                  returns (uint256)
              {
                  return bytes32ToUint(stringToBytes32(source));
              }
              
              function validUsername(string _username)
                  public
                  pure
                  returns(bool)
              {
                  bytes memory b = bytes(_username);
                  // Im Raum [4, 18]
                  if ((b.length < 4) || (b.length > 18)) return false;
                  // Letzte Char != ' '
                  
                  for(uint i; i<b.length; i++){
                      bytes1 char = b[i];
                      if(
                          !(char >= 0x30 && char <= 0x39) &&
                          !(char >= 0x41 && char <= 0x5A) //A-Z
                      )
                          return false;
                  }
                  
                  if (b[0] >= 0x30 && b[0] <= 0x39) return false;
                  
                  return true;
              }   
          }
          
          interface DAAInterface {
              function citizenMintToken(address _buyer, uint256 _buyPrice, int8 _is_win) external returns(uint256);
              function transfer(address _to, uint256 _value) external returns(bool);
              function transferFrom(address _from, address _to, uint256 _tokenAmount) external returns(bool);
              function balanceOf(address _from) external returns(uint256);
              function currentRoundDividend() external;
              function getDividendView(address _sender) external returns(uint256);
              function getDividendPull(address _sender, uint256 _value) external returns(uint256);
              function payOut(address _winner, uint256 _unit, uint256 _value, uint256 _valuebet) external;
              function getCitizenBalanceEth(address _sender) external returns(uint256);
              function totalSupplyByAddress(address _sender) external returns(uint256);
          }
          
          interface TicketInterface{
              function getEarlyIncomePull(address _sender) external returns(uint256);
              function getEarlyIncomeView(address _sender, bool _current) external returns(uint256); 
              function getEarlyIncomeByRound(address _buyer, uint256 _round) external returns(uint256);
              function currentRound() external returns(uint256);
              function ticketSumByAddress(address _sender) external returns(uint256);
          }
          
          contract CitizenStorage{
              using SafeMath for uint256;
              
              address controller; 
              modifier onlyCoreContract() {
                  require(msg.sender == controller, "admin required");
                  _;
              }
              
              mapping (address => uint256) public citizenWinIncome;
              mapping (address => uint256) public citizenGameWinIncome;
              mapping (address => uint256) public citizenWithdrawed;
              
              function addWinIncome(address _citizen, uint256 _value) public onlyCoreContract() {
                   citizenWinIncome[_citizen] = _value.add(citizenWinIncome[_citizen]);
                   citizenWithdrawed[_citizen] = citizenWithdrawed[_citizen].add(_value);
              }
              function addGameWinIncome(address _citizen, uint256 _value, bool _enough) public onlyCoreContract() {
                  citizenGameWinIncome[_citizen] = _value.add(citizenGameWinIncome[_citizen]);
                  if (_enough){
                      citizenWithdrawed[_citizen] = citizenWithdrawed[_citizen].add(_value);
                  }
              }
              function pushCitizenWithdrawed(address _sender, uint256 _value) public onlyCoreContract(){
                  citizenWithdrawed[_sender] = citizenWithdrawed[_sender].add(_value);
              }
              constructor (address _contract)
                  public
              {
                  require(controller== 0x0, "require setup");
                  controller = _contract;
              }
          }
          
          contract Citizen{
              using SafeMath for uint256;
              
              // event Register(uint256 id, uint256 username, address indexed citizen, address indexed ref,
              //                 uint256 ticket, uint256 ticketSpend, uint256 totalGameSpend, uint256 totalMined,
              //                 uint256 dateJoin, uint256 totalWithdraw);
                              
              event Register(uint256 id, uint256 username, address indexed citizen, address indexed ref, uint256 ticketSpend, uint256 totalGameSpend, uint256 dateJoin);
              modifier onlyAdmin() {
                  require(msg.sender == devTeam1, "admin required");
                  _;
              }
              
              modifier onlyCoreContract() {
                  require(isCoreContract[msg.sender], "admin required");
                  _;
              }
          
              modifier notRegistered(){
                  require(!isCitizen[msg.sender], "already exist");
                  _;
              }
          
              modifier registered(){
                  require(isCitizen[msg.sender], "must be a citizen");
                  _;
              }
              
              uint8[10] public TICKET_LEVEL_REF = [uint8(60),40,20,10,10,10,5,5,5,5];// 3 demical
              uint8[10] public GAME_LEVEL_REF = [uint8(5),2,1,1,1,1,1,1,1,1];// 3 demical
              
              
              struct Profile{
                  uint256 id;
                  uint256 username;
                  address ref;
                  mapping(uint => address[]) refTo;
                  mapping(address => uint256) payOut;
                  uint256 totalChild;
                  uint256 treeLevel;
                  
                  uint256 citizenBalanceEth;
                  uint256 citizenBalanceEthBackup;
                  
                  uint256 citizenTicketSpend;
                  uint256 citizenGameEthSpend;
                  uint256 citizenGameTokenSpend;
                  
                  
                  uint256 citizenEarlyIncomeRevenue;
                  uint256 citizenTicketRevenue;
                  uint256 citizenGameEthRevenue;
                  uint256 citizenGameTokenRevenue;
              }
          
          
              
              mapping (address => uint256) public citizenEthDividend;
          
              address[21] public mostTotalSpender;
              mapping (address => uint256) public mostTotalSpenderId;
              mapping (address => mapping(uint256 => uint256)) public payOutByLevel;
              
              mapping (address => Profile) public citizen;
              mapping (address => bool) public isCitizen;
              mapping (uint256 => address) public idAddress;
              mapping (uint256 => address) public usernameAddress;
              mapping (uint256 => address[]) public levelCitizen;
          
          
              address devTeam1; 
              address devTeam2; 
              address devTeam3; 
              address devTeam4;
              
              uint256 public citizenNr;
              uint256 lastLevel;
              
              uint256 earlyIncomeBalanceEth;
              
              DAAInterface public DAAContract;
              TicketInterface public TicketContract;
              CitizenStorage public CitizenStorageContract;
              mapping (address => bool) public isCoreContract;
              uint256 public coreContractSum;
              address[] public coreContracts;
              
          
              constructor (address[4] _devTeam)
                  public
              {
                  devTeam1 = _devTeam[0];
                  devTeam2 = _devTeam[1];
                  devTeam3 = _devTeam[2];
                  devTeam4 = _devTeam[3];
          
                  // first citizen is the development team
                  citizenNr = 1;
                  idAddress[1] = devTeam3;
                  isCitizen[devTeam3] = true;
                  //root => self ref
                  citizen[devTeam3].ref = devTeam3;
                  // username rules bypass
                  uint256 _username = Helper.stringToUint("GLOBAL");
                  citizen[devTeam3].username = _username;
                  usernameAddress[_username] = devTeam3; 
                  citizen[devTeam3].id = 1;
                  citizen[devTeam3].treeLevel = 1;
                  levelCitizen[1].push(devTeam3);
                  lastLevel = 1;
              }
              
              // DAAContract, TicketContract, CitizenContract, CitizenStorage 
              function joinNetwork(address[4] _contract)
                  public
              {
                  require(address(DAAContract) == 0x0,"already setup");
                  DAAContract = DAAInterface(_contract[0]);
                  TicketContract = TicketInterface(_contract[1]);
                  CitizenStorageContract = CitizenStorage(_contract[3]);
                  for(uint256 i =0; i<3; i++){
                      isCoreContract[_contract[i]]=true;
                      coreContracts.push(_contract[i]);
                  }
                  coreContractSum = 3;
              }
          
              function updateTotalChild(address _address)
                  private
              {
                  address _member = _address;
                  while(_member != devTeam3) {
                      _member = getRef(_member);
                      citizen[_member].totalChild ++;
                  }
              }
              
              function addCoreContract(address _address) public  // [dev1]
                  onlyAdmin()
              {
                  require(_address!=0x0,"Invalid address");
                  isCoreContract[_address] = true;
                  coreContracts.push(_address);
                  coreContractSum+=1;
              }
              
              function updateRefTo(address _address) private {
                  address _member = _address;
                  uint256 level =1;
                  while (_member != devTeam3 && level<11){
                      _member = getRef(_member);
                      citizen[_member].refTo[level].push(_address);
                      level = level+1;
                  }
              }
          
              function register(string _sUsername, address _ref)
                  public
                  notRegistered()
              {
                  require(Helper.validUsername(_sUsername), "invalid username");
                  address sender = msg.sender;
                  uint256 _username = Helper.stringToUint(_sUsername);
                  require(usernameAddress[_username] == 0x0, "username already exist");
                  usernameAddress[_username] = sender;
                  //ref must be a citizen, else ref = devTeam
                  address validRef = isCitizen[_ref] ? _ref : devTeam3;
          
                  //Welcome new Citizen
                  isCitizen[sender] = true;
                  citizen[sender].username = _username;
                  citizen[sender].ref = validRef;
                  citizenNr++;
          
                  idAddress[citizenNr] = sender;
                  citizen[sender].id = citizenNr;
                  
                  uint256 refLevel = citizen[validRef].treeLevel;
                  if (refLevel == lastLevel) lastLevel++;
                  citizen[sender].treeLevel = refLevel + 1;
                  levelCitizen[refLevel + 1].push(sender);
                  //add child
                  updateRefTo(sender);
                  updateTotalChild(sender);
                  emit Register(citizenNr,_username, sender, validRef, citizen[sender].citizenTicketSpend, citizen[sender].citizenGameEthSpend, now);
              }
              
              // function updateUsername(string _sNewUsername)
              //     public
              //     registered()
              // {
              //     require(Helper.validUsername(_sNewUsername), "invalid username");
              //     address sender = msg.sender;
              //     uint256 _newUsername = Helper.stringToUint(_sNewUsername);
              //     require(usernameAddress[_newUsername] == 0x0, "username already exist");
              //     uint256 _oldUsername = citizen[sender].username;
              //     citizen[sender].username = _newUsername;
              //     usernameAddress[_oldUsername] = 0x0;
              //     usernameAddress[_newUsername] = sender;
              // }
          
              function getRef(address _address)
                  public
                  view
                  returns (address)
              {
                  return citizen[_address].ref == 0x0 ? devTeam3 : citizen[_address].ref;
              }
              
              function getUsername(address _address)
                  public
                  view
                  returns (uint256)
              {
                  return citizen[_address].username;
              }
              
              function isDev() public view returns(bool){
                  if (msg.sender == devTeam1) return true;
                  return false;
              }
              
              function getAddressById(uint256 _id)
                  public
                  view
                  returns (address)
              {
                  return idAddress[_id];
              }
          
              function getAddressByUserName(string _username)
                  public
                  view
                  returns (address)
              {
                  return usernameAddress[Helper.stringToUint(_username)];
              }
              
              function pushTicketRefIncome(address _sender)
                  public
                  payable
                  onlyCoreContract() 
              {
                  uint256 _amount = msg.value; // 17%
                  _amount = _amount.div(170);
                  address sender = _sender;
                  address ref = getRef(sender);
                  uint256 money;
                  uint8 level;
                  
                  for (level=0; level<10; level++){
                      money = _amount.mul(TICKET_LEVEL_REF[level]);
                      citizen[ref].citizenBalanceEth = money.add(citizen[ref].citizenBalanceEth);
                      citizen[ref].citizenTicketRevenue = money.add(citizen[ref].citizenTicketRevenue);
                      citizen[ref].payOut[_sender] = money.add(citizen[ref].payOut[_sender]);
                      payOutByLevel[ref][level+1] = money.add(payOutByLevel[ref][level+1]);
                      sender = ref;
                      ref = getRef(sender);
                  }
              }    
              
              function pushGametRefIncome(address _sender)
                  public
                  payable
                  onlyCoreContract() 
              {
                  uint256 _amount =  msg.value; // 1.5%
                  _amount = _amount.div(15);
                  address sender = _sender;
                  address ref = getRef(sender);
                  uint256 level;
                  uint256 money;
                  uint256 forDaa;
                  for (level=0; level<10; level++){
                      forDaa=0;
                      money = _amount.mul(GAME_LEVEL_REF[level]);
                      if (citizen[ref].citizenGameEthRevenue<citizen[ref].citizenGameEthSpend.div(10)){
                          if (citizen[ref].citizenGameEthRevenue+money>citizen[ref].citizenGameEthSpend.div(10)){
                              forDaa = citizen[ref].citizenGameEthRevenue+money-citizen[ref].citizenGameEthSpend.div(10);
                              money = money.sub(forDaa);
                          }
                      } else {
                          forDaa = money;
                          money = 0;
                      }
                      
                      citizen[ref].citizenBalanceEth = money.add(citizen[ref].citizenBalanceEth);
                      citizen[ref].citizenGameEthRevenue = money.add(citizen[ref].citizenGameEthRevenue);
                      citizen[ref].payOut[_sender] = money.add(citizen[ref].payOut[_sender]);
                      payOutByLevel[ref][level+1] = money.add(payOutByLevel[ref][level+1]);
                      
                      citizen[devTeam3].citizenBalanceEth = forDaa.add(citizen[devTeam3].citizenBalanceEth);
                      citizen[devTeam3].citizenGameEthRevenue = forDaa.add(citizen[devTeam3].citizenGameEthRevenue);
                      
                      sender = ref;
                      ref = getRef(sender);
                  }
              }    
              function pushGametRefIncomeToken(address _sender, uint256 _amount)
                  public
                  payable
                  onlyCoreContract() 
              {
                  _amount = _amount.div(15);
                  address sender = _sender;
                  address ref = getRef(sender);
                  uint256 level;
                  uint256 money;
                  uint256 forDaa;
                  
                  for (level=0; level<10; level++){
                      forDaa=0;
                      money = _amount.mul(GAME_LEVEL_REF[level]);
                      if (citizen[ref].citizenGameTokenRevenue<citizen[ref].citizenGameTokenSpend.div(10)){
                          if (citizen[ref].citizenGameTokenRevenue+money>citizen[ref].citizenGameTokenSpend.div(10)){
                              forDaa = citizen[ref].citizenGameTokenRevenue+money-citizen[ref].citizenGameTokenSpend.div(10);
                              money = money.sub(forDaa);
                          }
                      } else {
                          forDaa = money;
                          money = 0;
                      }
                      
                      DAAContract.payOut(ref,1,money,0);
                      citizen[ref].citizenGameTokenRevenue=money.add(citizen[ref].citizenGameTokenRevenue);
                      
                      DAAContract.payOut(devTeam3,1,forDaa,0);
                      citizen[devTeam3].citizenGameTokenRevenue = forDaa.add(citizen[devTeam3].citizenGameTokenRevenue);
                      
                      sender = ref;
                      ref = getRef(sender);
                  }
              }
              
              function pushEarlyIncome() public payable{
                  uint256 _value = msg.value;
                  earlyIncomeBalanceEth = earlyIncomeBalanceEth.add(_value);
              }
              
              function sortMostSpend(address _citizen) private {
                  uint256 citizen_spender = getTotalSpend(_citizen);
                  uint256 i=1;
                  while (i<21) {
                      if (mostTotalSpender[i]==0x0||(mostTotalSpender[i]!=0x0&&getTotalSpend(mostTotalSpender[i])<citizen_spender)){
                          if (mostTotalSpenderId[_citizen]!=0&&mostTotalSpenderId[_citizen]<i){
                              break;
                          }
                          if (mostTotalSpenderId[_citizen]!=0){
                              mostTotalSpender[mostTotalSpenderId[_citizen]]=0x0;
                          }
                          address temp1 = mostTotalSpender[i];
                          address temp2;
                          uint256 j=i+1;
                          while (j<21&&temp1!=0x0){
                              temp2 = mostTotalSpender[j];
                              mostTotalSpender[j]=temp1;
                              mostTotalSpenderId[temp1]=j;
                              temp1 = temp2;
                              j++;
                          }
                          mostTotalSpender[i]=_citizen;
                          mostTotalSpenderId[_citizen]=i;
                          break;
                      }
                      i++;
                  }
              }
              
              function addTicketEthSpend(address _citizen, uint256 _value) onlyCoreContract() public {
                  citizen[_citizen].citizenTicketSpend = citizen[_citizen].citizenTicketSpend.add(_value);
                  DAAContract.citizenMintToken(_citizen,_value,0);// buy ticket 0, win 1, lose -1;
                  sortMostSpend(_citizen);
              }   
              
              // Game spend 
              function addGameEthSpendWin(address _citizen, uint256 _value, uint256 _valuewin, bool _enough) onlyCoreContract() public {
                  citizen[_citizen].citizenGameEthSpend = citizen[_citizen].citizenGameEthSpend.add(_value);
                  // DAAContract.citizenMintToken(_citizen,_value,1);// buy ticket 0, win 1, lose -1;
                  CitizenStorageContract.addGameWinIncome(_citizen, _valuewin, _enough);
                  sortMostSpend(_citizen);
              }     
              function addGameEthSpendLose(address _citizen, uint256 _value) onlyCoreContract() public {
                  citizen[_citizen].citizenGameEthSpend = citizen[_citizen].citizenGameEthSpend.add(_value);
                  DAAContract.citizenMintToken(_citizen,_value,-1);// buy ticket 0, win 1, lose -1;
                  sortMostSpend(_citizen);
              }    
              function addGameTokenSpend(address _citizen, uint256 _value) onlyCoreContract() public {
                  citizen[_citizen].citizenGameTokenSpend = citizen[_citizen].citizenGameTokenSpend.add(_value);
              }
              
              function withdrawEth() public registered() {
                  address _sender = msg.sender;
                  uint256 _earlyIncome = TicketContract.getEarlyIncomePull(_sender);
                  uint256 _devidend = DAAContract.getDividendView(msg.sender);
                  uint256 _citizenBalanceEth = citizen[_sender].citizenBalanceEth;
                  uint256 _total = _earlyIncome.add(_devidend).add(_citizenBalanceEth).add(DAAContract.getCitizenBalanceEth(_sender));
                  require(_total>0,"Balance none");
                  CitizenStorageContract.pushCitizenWithdrawed(_sender,_total);
                  DAAContract.getDividendPull(_sender,_citizenBalanceEth+_earlyIncome);
                  _sender.transfer(_citizenBalanceEth+_earlyIncome);
                  citizen[_sender].citizenBalanceEthBackup = citizen[_sender].citizenBalanceEthBackup.add(_citizenBalanceEth).add(_earlyIncome).add(_devidend);
                  citizen[_sender].citizenEarlyIncomeRevenue = citizen[_sender].citizenEarlyIncomeRevenue.add(_earlyIncome);
                  citizenEthDividend[_sender] = citizenEthDividend[_sender].add(_devidend);
                  earlyIncomeBalanceEth= earlyIncomeBalanceEth.sub(_earlyIncome);
                  citizen[_sender].citizenBalanceEth = 0;
              }
              
              function addWinIncome(address _citizen, uint256 _value)  onlyCoreContract()  public {
                  CitizenStorageContract.addWinIncome(_citizen, _value); 
              }
              // function addGameWinIncome(address _citizen, uint256 _value, bool _enough) public {
              //     CitizenStorageContract.addGameWinIncome(_citizen, _value, _enough);
              // }
              
              // function getInWallet() public view returns (uint256){
              //     uint256 _sum;
              //     address _sender = msg.sender;
              //     _sum = _sum.add(citizen[_sender].citizenBalanceEth);
              //     _sum = _sum.add(TicketContract.getEarlyIncomeView(_sender));
              //     _sum = _sum.add(DAAContract.getDividendView(_sender));
              //     _sum = _sum.add(DAAContract.getCitizenBalanceEth(_sender));
              //     return _sum;
              // }  
              
              function getTotalEth() public registered() view returns(uint256){
                  uint256 _sum;
                  address _sender = msg.sender;
                  _sum = _sum.add(citizen[_sender].citizenBalanceEth);
                  _sum = _sum.add(citizen[_sender].citizenBalanceEthBackup);
                  _sum = _sum.add(CitizenStorageContract.citizenWinIncome(_sender));
                  _sum = _sum.add(TicketContract.getEarlyIncomeView(_sender, false));
                  _sum = _sum.add(DAAContract.getDividendView(_sender));
                  return _sum;
              }
              
              function getTotalDividend(address _sender) public registered() view returns(uint256){
                  return citizenEthDividend[_sender].add(DAAContract.getDividendView(_sender));
              }
              
              function getTotalEarlyIncome(address _sender) public registered() view returns(uint256){
                  uint256 _sum;
                  _sum = citizen[_sender].citizenEarlyIncomeRevenue;
                  _sum = _sum.add(TicketContract.getEarlyIncomeView(_sender, true));
                  return _sum;
              }
              
              function getTotalSpend(address _sender) public view returns(uint256){
                  return citizen[_sender].citizenGameEthSpend+citizen[_sender].citizenTicketSpend;
              }
              
              function getMemberByLevelToTal(uint256 _level) public view returns(uint256, uint256){
                  address _sender = msg.sender;
                  return(citizen[_sender].refTo[_level].length,payOutByLevel[_sender][_level]);
              }
              
              function getMemberByLevel(uint256 _level, address _sender, uint256 _id) public view returns(address){
                  return citizen[_sender].refTo[_level][_id];
              }
              
              function citizenPayForRef(address _citizen, address _ref) public view returns(uint256){
                  return citizen[_ref].payOut[_citizen];
              }
          }

          File 3 of 3: CitizenStorage
          pragma solidity ^0.4.24;
          // pragma experimental ABIEncoderV2;
          /**
           * @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;
              }
          }
          
          
          library Helper {
              using SafeMath for uint256;
              
                  
              function bytes32ToUint(bytes32 n) 
                  public
                  pure
                  returns (uint256) 
              {
                  return uint256(n);
              }
              
              function stringToBytes32(string memory source) 
                  public
                  pure
                  returns (bytes32 result) 
              {
                  bytes memory tempEmptyStringTest = bytes(source);
                  if (tempEmptyStringTest.length == 0) {
                      return 0x0;
                  }
          
                  assembly {
                      result := mload(add(source, 32))
                  }
              }
              
              function stringToUint(string memory source) 
                  public
                  pure
                  returns (uint256)
              {
                  return bytes32ToUint(stringToBytes32(source));
              }
              
              function validUsername(string _username)
                  public
                  pure
                  returns(bool)
              {
                  bytes memory b = bytes(_username);
                  // Im Raum [4, 18]
                  if ((b.length < 4) || (b.length > 18)) return false;
                  // Letzte Char != ' '
                  
                  for(uint i; i<b.length; i++){
                      bytes1 char = b[i];
                      if(
                          !(char >= 0x30 && char <= 0x39) &&
                          !(char >= 0x41 && char <= 0x5A) //A-Z
                      )
                          return false;
                  }
                  
                  if (b[0] >= 0x30 && b[0] <= 0x39) return false;
                  
                  return true;
              }   
          }
          
          interface DAAInterface {
              function citizenMintToken(address _buyer, uint256 _buyPrice, int8 _is_win) external returns(uint256);
              function transfer(address _to, uint256 _value) external returns(bool);
              function transferFrom(address _from, address _to, uint256 _tokenAmount) external returns(bool);
              function balanceOf(address _from) external returns(uint256);
              function currentRoundDividend() external;
              function getDividendView(address _sender) external returns(uint256);
              function getDividendPull(address _sender, uint256 _value) external returns(uint256);
              function payOut(address _winner, uint256 _unit, uint256 _value, uint256 _valuebet) external;
              function getCitizenBalanceEth(address _sender) external returns(uint256);
              function totalSupplyByAddress(address _sender) external returns(uint256);
          }
          
          interface TicketInterface{
              function getEarlyIncomePull(address _sender) external returns(uint256);
              function getEarlyIncomeView(address _sender, bool _current) external returns(uint256); 
              function getEarlyIncomeByRound(address _buyer, uint256 _round) external returns(uint256);
              function currentRound() external returns(uint256);
              function ticketSumByAddress(address _sender) external returns(uint256);
          }
          
          contract CitizenStorage{
              using SafeMath for uint256;
              
              address controller; 
              modifier onlyCoreContract() {
                  require(msg.sender == controller, "admin required");
                  _;
              }
              
              mapping (address => uint256) public citizenWinIncome;
              mapping (address => uint256) public citizenGameWinIncome;
              mapping (address => uint256) public citizenWithdrawed;
              
              function addWinIncome(address _citizen, uint256 _value) public onlyCoreContract() {
                   citizenWinIncome[_citizen] = _value.add(citizenWinIncome[_citizen]);
                   citizenWithdrawed[_citizen] = citizenWithdrawed[_citizen].add(_value);
              }
              function addGameWinIncome(address _citizen, uint256 _value, bool _enough) public onlyCoreContract() {
                  citizenGameWinIncome[_citizen] = _value.add(citizenGameWinIncome[_citizen]);
                  if (_enough){
                      citizenWithdrawed[_citizen] = citizenWithdrawed[_citizen].add(_value);
                  }
              }
              function pushCitizenWithdrawed(address _sender, uint256 _value) public onlyCoreContract(){
                  citizenWithdrawed[_sender] = citizenWithdrawed[_sender].add(_value);
              }
              constructor (address _contract)
                  public
              {
                  require(controller== 0x0, "require setup");
                  controller = _contract;
              }
          }
          
          contract Citizen{
              using SafeMath for uint256;
              
              // event Register(uint256 id, uint256 username, address indexed citizen, address indexed ref,
              //                 uint256 ticket, uint256 ticketSpend, uint256 totalGameSpend, uint256 totalMined,
              //                 uint256 dateJoin, uint256 totalWithdraw);
                              
              event Register(uint256 id, uint256 username, address indexed citizen, address indexed ref, uint256 ticketSpend, uint256 totalGameSpend, uint256 dateJoin);
              modifier onlyAdmin() {
                  require(msg.sender == devTeam1, "admin required");
                  _;
              }
              
              modifier onlyCoreContract() {
                  require(isCoreContract[msg.sender], "admin required");
                  _;
              }
          
              modifier notRegistered(){
                  require(!isCitizen[msg.sender], "already exist");
                  _;
              }
          
              modifier registered(){
                  require(isCitizen[msg.sender], "must be a citizen");
                  _;
              }
              
              uint8[10] public TICKET_LEVEL_REF = [uint8(60),40,20,10,10,10,5,5,5,5];// 3 demical
              uint8[10] public GAME_LEVEL_REF = [uint8(5),2,1,1,1,1,1,1,1,1];// 3 demical
              
              
              struct Profile{
                  uint256 id;
                  uint256 username;
                  address ref;
                  mapping(uint => address[]) refTo;
                  mapping(address => uint256) payOut;
                  uint256 totalChild;
                  uint256 treeLevel;
                  
                  uint256 citizenBalanceEth;
                  uint256 citizenBalanceEthBackup;
                  
                  uint256 citizenTicketSpend;
                  uint256 citizenGameEthSpend;
                  uint256 citizenGameTokenSpend;
                  
                  
                  uint256 citizenEarlyIncomeRevenue;
                  uint256 citizenTicketRevenue;
                  uint256 citizenGameEthRevenue;
                  uint256 citizenGameTokenRevenue;
              }
          
          
              
              mapping (address => uint256) public citizenEthDividend;
          
              address[21] public mostTotalSpender;
              mapping (address => uint256) public mostTotalSpenderId;
              mapping (address => mapping(uint256 => uint256)) public payOutByLevel;
              
              mapping (address => Profile) public citizen;
              mapping (address => bool) public isCitizen;
              mapping (uint256 => address) public idAddress;
              mapping (uint256 => address) public usernameAddress;
              mapping (uint256 => address[]) public levelCitizen;
          
          
              address devTeam1; 
              address devTeam2; 
              address devTeam3; 
              address devTeam4;
              
              uint256 public citizenNr;
              uint256 lastLevel;
              
              uint256 earlyIncomeBalanceEth;
              
              DAAInterface public DAAContract;
              TicketInterface public TicketContract;
              CitizenStorage public CitizenStorageContract;
              mapping (address => bool) public isCoreContract;
              uint256 public coreContractSum;
              address[] public coreContracts;
              
          
              constructor (address[4] _devTeam)
                  public
              {
                  devTeam1 = _devTeam[0];
                  devTeam2 = _devTeam[1];
                  devTeam3 = _devTeam[2];
                  devTeam4 = _devTeam[3];
          
                  // first citizen is the development team
                  citizenNr = 1;
                  idAddress[1] = devTeam3;
                  isCitizen[devTeam3] = true;
                  //root => self ref
                  citizen[devTeam3].ref = devTeam3;
                  // username rules bypass
                  uint256 _username = Helper.stringToUint("GLOBAL");
                  citizen[devTeam3].username = _username;
                  usernameAddress[_username] = devTeam3; 
                  citizen[devTeam3].id = 1;
                  citizen[devTeam3].treeLevel = 1;
                  levelCitizen[1].push(devTeam3);
                  lastLevel = 1;
              }
              
              // DAAContract, TicketContract, CitizenContract, CitizenStorage 
              function joinNetwork(address[4] _contract)
                  public
              {
                  require(address(DAAContract) == 0x0,"already setup");
                  DAAContract = DAAInterface(_contract[0]);
                  TicketContract = TicketInterface(_contract[1]);
                  CitizenStorageContract = CitizenStorage(_contract[3]);
                  for(uint256 i =0; i<3; i++){
                      isCoreContract[_contract[i]]=true;
                      coreContracts.push(_contract[i]);
                  }
                  coreContractSum = 3;
              }
          
              function updateTotalChild(address _address)
                  private
              {
                  address _member = _address;
                  while(_member != devTeam3) {
                      _member = getRef(_member);
                      citizen[_member].totalChild ++;
                  }
              }
              
              function addCoreContract(address _address) public  // [dev1]
                  onlyAdmin()
              {
                  require(_address!=0x0,"Invalid address");
                  isCoreContract[_address] = true;
                  coreContracts.push(_address);
                  coreContractSum+=1;
              }
              
              function updateRefTo(address _address) private {
                  address _member = _address;
                  uint256 level =1;
                  while (_member != devTeam3 && level<11){
                      _member = getRef(_member);
                      citizen[_member].refTo[level].push(_address);
                      level = level+1;
                  }
              }
          
              function register(string _sUsername, address _ref)
                  public
                  notRegistered()
              {
                  require(Helper.validUsername(_sUsername), "invalid username");
                  address sender = msg.sender;
                  uint256 _username = Helper.stringToUint(_sUsername);
                  require(usernameAddress[_username] == 0x0, "username already exist");
                  usernameAddress[_username] = sender;
                  //ref must be a citizen, else ref = devTeam
                  address validRef = isCitizen[_ref] ? _ref : devTeam3;
          
                  //Welcome new Citizen
                  isCitizen[sender] = true;
                  citizen[sender].username = _username;
                  citizen[sender].ref = validRef;
                  citizenNr++;
          
                  idAddress[citizenNr] = sender;
                  citizen[sender].id = citizenNr;
                  
                  uint256 refLevel = citizen[validRef].treeLevel;
                  if (refLevel == lastLevel) lastLevel++;
                  citizen[sender].treeLevel = refLevel + 1;
                  levelCitizen[refLevel + 1].push(sender);
                  //add child
                  updateRefTo(sender);
                  updateTotalChild(sender);
                  emit Register(citizenNr,_username, sender, validRef, citizen[sender].citizenTicketSpend, citizen[sender].citizenGameEthSpend, now);
              }
              
              // function updateUsername(string _sNewUsername)
              //     public
              //     registered()
              // {
              //     require(Helper.validUsername(_sNewUsername), "invalid username");
              //     address sender = msg.sender;
              //     uint256 _newUsername = Helper.stringToUint(_sNewUsername);
              //     require(usernameAddress[_newUsername] == 0x0, "username already exist");
              //     uint256 _oldUsername = citizen[sender].username;
              //     citizen[sender].username = _newUsername;
              //     usernameAddress[_oldUsername] = 0x0;
              //     usernameAddress[_newUsername] = sender;
              // }
          
              function getRef(address _address)
                  public
                  view
                  returns (address)
              {
                  return citizen[_address].ref == 0x0 ? devTeam3 : citizen[_address].ref;
              }
              
              function getUsername(address _address)
                  public
                  view
                  returns (uint256)
              {
                  return citizen[_address].username;
              }
              
              function isDev() public view returns(bool){
                  if (msg.sender == devTeam1) return true;
                  return false;
              }
              
              function getAddressById(uint256 _id)
                  public
                  view
                  returns (address)
              {
                  return idAddress[_id];
              }
          
              function getAddressByUserName(string _username)
                  public
                  view
                  returns (address)
              {
                  return usernameAddress[Helper.stringToUint(_username)];
              }
              
              function pushTicketRefIncome(address _sender)
                  public
                  payable
                  onlyCoreContract() 
              {
                  uint256 _amount = msg.value; // 17%
                  _amount = _amount.div(170);
                  address sender = _sender;
                  address ref = getRef(sender);
                  uint256 money;
                  uint8 level;
                  
                  for (level=0; level<10; level++){
                      money = _amount.mul(TICKET_LEVEL_REF[level]);
                      citizen[ref].citizenBalanceEth = money.add(citizen[ref].citizenBalanceEth);
                      citizen[ref].citizenTicketRevenue = money.add(citizen[ref].citizenTicketRevenue);
                      citizen[ref].payOut[_sender] = money.add(citizen[ref].payOut[_sender]);
                      payOutByLevel[ref][level+1] = money.add(payOutByLevel[ref][level+1]);
                      sender = ref;
                      ref = getRef(sender);
                  }
              }    
              
              function pushGametRefIncome(address _sender)
                  public
                  payable
                  onlyCoreContract() 
              {
                  uint256 _amount =  msg.value; // 1.5%
                  _amount = _amount.div(15);
                  address sender = _sender;
                  address ref = getRef(sender);
                  uint256 level;
                  uint256 money;
                  uint256 forDaa;
                  for (level=0; level<10; level++){
                      forDaa=0;
                      money = _amount.mul(GAME_LEVEL_REF[level]);
                      if (citizen[ref].citizenGameEthRevenue<citizen[ref].citizenGameEthSpend.div(10)){
                          if (citizen[ref].citizenGameEthRevenue+money>citizen[ref].citizenGameEthSpend.div(10)){
                              forDaa = citizen[ref].citizenGameEthRevenue+money-citizen[ref].citizenGameEthSpend.div(10);
                              money = money.sub(forDaa);
                          }
                      } else {
                          forDaa = money;
                          money = 0;
                      }
                      
                      citizen[ref].citizenBalanceEth = money.add(citizen[ref].citizenBalanceEth);
                      citizen[ref].citizenGameEthRevenue = money.add(citizen[ref].citizenGameEthRevenue);
                      citizen[ref].payOut[_sender] = money.add(citizen[ref].payOut[_sender]);
                      payOutByLevel[ref][level+1] = money.add(payOutByLevel[ref][level+1]);
                      
                      citizen[devTeam3].citizenBalanceEth = forDaa.add(citizen[devTeam3].citizenBalanceEth);
                      citizen[devTeam3].citizenGameEthRevenue = forDaa.add(citizen[devTeam3].citizenGameEthRevenue);
                      
                      sender = ref;
                      ref = getRef(sender);
                  }
              }    
              function pushGametRefIncomeToken(address _sender, uint256 _amount)
                  public
                  payable
                  onlyCoreContract() 
              {
                  _amount = _amount.div(15);
                  address sender = _sender;
                  address ref = getRef(sender);
                  uint256 level;
                  uint256 money;
                  uint256 forDaa;
                  
                  for (level=0; level<10; level++){
                      forDaa=0;
                      money = _amount.mul(GAME_LEVEL_REF[level]);
                      if (citizen[ref].citizenGameTokenRevenue<citizen[ref].citizenGameTokenSpend.div(10)){
                          if (citizen[ref].citizenGameTokenRevenue+money>citizen[ref].citizenGameTokenSpend.div(10)){
                              forDaa = citizen[ref].citizenGameTokenRevenue+money-citizen[ref].citizenGameTokenSpend.div(10);
                              money = money.sub(forDaa);
                          }
                      } else {
                          forDaa = money;
                          money = 0;
                      }
                      
                      DAAContract.payOut(ref,1,money,0);
                      citizen[ref].citizenGameTokenRevenue=money.add(citizen[ref].citizenGameTokenRevenue);
                      
                      DAAContract.payOut(devTeam3,1,forDaa,0);
                      citizen[devTeam3].citizenGameTokenRevenue = forDaa.add(citizen[devTeam3].citizenGameTokenRevenue);
                      
                      sender = ref;
                      ref = getRef(sender);
                  }
              }
              
              function pushEarlyIncome() public payable{
                  uint256 _value = msg.value;
                  earlyIncomeBalanceEth = earlyIncomeBalanceEth.add(_value);
              }
              
              function sortMostSpend(address _citizen) private {
                  uint256 citizen_spender = getTotalSpend(_citizen);
                  uint256 i=1;
                  while (i<21) {
                      if (mostTotalSpender[i]==0x0||(mostTotalSpender[i]!=0x0&&getTotalSpend(mostTotalSpender[i])<citizen_spender)){
                          if (mostTotalSpenderId[_citizen]!=0&&mostTotalSpenderId[_citizen]<i){
                              break;
                          }
                          if (mostTotalSpenderId[_citizen]!=0){
                              mostTotalSpender[mostTotalSpenderId[_citizen]]=0x0;
                          }
                          address temp1 = mostTotalSpender[i];
                          address temp2;
                          uint256 j=i+1;
                          while (j<21&&temp1!=0x0){
                              temp2 = mostTotalSpender[j];
                              mostTotalSpender[j]=temp1;
                              mostTotalSpenderId[temp1]=j;
                              temp1 = temp2;
                              j++;
                          }
                          mostTotalSpender[i]=_citizen;
                          mostTotalSpenderId[_citizen]=i;
                          break;
                      }
                      i++;
                  }
              }
              
              function addTicketEthSpend(address _citizen, uint256 _value) onlyCoreContract() public {
                  citizen[_citizen].citizenTicketSpend = citizen[_citizen].citizenTicketSpend.add(_value);
                  DAAContract.citizenMintToken(_citizen,_value,0);// buy ticket 0, win 1, lose -1;
                  sortMostSpend(_citizen);
              }   
              
              // Game spend 
              function addGameEthSpendWin(address _citizen, uint256 _value, uint256 _valuewin, bool _enough) onlyCoreContract() public {
                  citizen[_citizen].citizenGameEthSpend = citizen[_citizen].citizenGameEthSpend.add(_value);
                  // DAAContract.citizenMintToken(_citizen,_value,1);// buy ticket 0, win 1, lose -1;
                  CitizenStorageContract.addGameWinIncome(_citizen, _valuewin, _enough);
                  sortMostSpend(_citizen);
              }     
              function addGameEthSpendLose(address _citizen, uint256 _value) onlyCoreContract() public {
                  citizen[_citizen].citizenGameEthSpend = citizen[_citizen].citizenGameEthSpend.add(_value);
                  DAAContract.citizenMintToken(_citizen,_value,-1);// buy ticket 0, win 1, lose -1;
                  sortMostSpend(_citizen);
              }    
              function addGameTokenSpend(address _citizen, uint256 _value) onlyCoreContract() public {
                  citizen[_citizen].citizenGameTokenSpend = citizen[_citizen].citizenGameTokenSpend.add(_value);
              }
              
              function withdrawEth() public registered() {
                  address _sender = msg.sender;
                  uint256 _earlyIncome = TicketContract.getEarlyIncomePull(_sender);
                  uint256 _devidend = DAAContract.getDividendView(msg.sender);
                  uint256 _citizenBalanceEth = citizen[_sender].citizenBalanceEth;
                  uint256 _total = _earlyIncome.add(_devidend).add(_citizenBalanceEth).add(DAAContract.getCitizenBalanceEth(_sender));
                  require(_total>0,"Balance none");
                  CitizenStorageContract.pushCitizenWithdrawed(_sender,_total);
                  DAAContract.getDividendPull(_sender,_citizenBalanceEth+_earlyIncome);
                  _sender.transfer(_citizenBalanceEth+_earlyIncome);
                  citizen[_sender].citizenBalanceEthBackup = citizen[_sender].citizenBalanceEthBackup.add(_citizenBalanceEth).add(_earlyIncome).add(_devidend);
                  citizen[_sender].citizenEarlyIncomeRevenue = citizen[_sender].citizenEarlyIncomeRevenue.add(_earlyIncome);
                  citizenEthDividend[_sender] = citizenEthDividend[_sender].add(_devidend);
                  earlyIncomeBalanceEth= earlyIncomeBalanceEth.sub(_earlyIncome);
                  citizen[_sender].citizenBalanceEth = 0;
              }
              
              function addWinIncome(address _citizen, uint256 _value)  onlyCoreContract()  public {
                  CitizenStorageContract.addWinIncome(_citizen, _value); 
              }
              // function addGameWinIncome(address _citizen, uint256 _value, bool _enough) public {
              //     CitizenStorageContract.addGameWinIncome(_citizen, _value, _enough);
              // }
              
              // function getInWallet() public view returns (uint256){
              //     uint256 _sum;
              //     address _sender = msg.sender;
              //     _sum = _sum.add(citizen[_sender].citizenBalanceEth);
              //     _sum = _sum.add(TicketContract.getEarlyIncomeView(_sender));
              //     _sum = _sum.add(DAAContract.getDividendView(_sender));
              //     _sum = _sum.add(DAAContract.getCitizenBalanceEth(_sender));
              //     return _sum;
              // }  
              
              function getTotalEth() public registered() view returns(uint256){
                  uint256 _sum;
                  address _sender = msg.sender;
                  _sum = _sum.add(citizen[_sender].citizenBalanceEth);
                  _sum = _sum.add(citizen[_sender].citizenBalanceEthBackup);
                  _sum = _sum.add(CitizenStorageContract.citizenWinIncome(_sender));
                  _sum = _sum.add(TicketContract.getEarlyIncomeView(_sender, false));
                  _sum = _sum.add(DAAContract.getDividendView(_sender));
                  return _sum;
              }
              
              function getTotalDividend(address _sender) public registered() view returns(uint256){
                  return citizenEthDividend[_sender].add(DAAContract.getDividendView(_sender));
              }
              
              function getTotalEarlyIncome(address _sender) public registered() view returns(uint256){
                  uint256 _sum;
                  _sum = citizen[_sender].citizenEarlyIncomeRevenue;
                  _sum = _sum.add(TicketContract.getEarlyIncomeView(_sender, true));
                  return _sum;
              }
              
              function getTotalSpend(address _sender) public view returns(uint256){
                  return citizen[_sender].citizenGameEthSpend+citizen[_sender].citizenTicketSpend;
              }
              
              function getMemberByLevelToTal(uint256 _level) public view returns(uint256, uint256){
                  address _sender = msg.sender;
                  return(citizen[_sender].refTo[_level].length,payOutByLevel[_sender][_level]);
              }
              
              function getMemberByLevel(uint256 _level, address _sender, uint256 _id) public view returns(address){
                  return citizen[_sender].refTo[_level][_id];
              }
              
              function citizenPayForRef(address _citizen, address _ref) public view returns(uint256){
                  return citizen[_ref].payOut[_citizen];
              }
          }