function renewDec(uint initSum, uint newSum) internal returns(bool success){

        if(round < 9){
            uint tempInitSum = initSum; 
            uint tempNewSum = newSum; 
            uint cnt = 1;

            while( (tempNewSum > 0 || tempInitSum > 0) && cnt <= decimals ){

                uint lastInitSum = tempInitSum%10; 
                tempInitSum = tempInitSum/10; 

                uint lastNewSum = tempNewSum%10; 
                tempNewSum = tempNewSum/10; 

                if(cnt >= round){
                    if(lastNewSum >= lastInitSum){
                        
                        dec[decimals-cnt] = dec[decimals-cnt].add(lastNewSum - lastInitSum);
                    }else{
                        
                        dec[decimals-cnt] = dec[decimals-cnt].sub(lastInitSum - lastNewSum);
                    }
                }

                cnt = cnt+1;
            }
        }

        return true;
    }



    
    
    
    function bitmask_add(address user, uint _bit) internal returns(bool success){ 
        require(bitmask_check(user, _bit) == false);
        accounts[user].bitmask = accounts[user].bitmask.add(_bit);
        return true;
    }
    
    
    function bitmask_rm(address user, uint _bit) internal returns(bool success){
        require(bitmask_check(user, _bit) == true);
        accounts[user].bitmask = accounts[user].bitmask.sub(_bit);
        return true;
    }
    
    function bitmask_check(address user, uint _bit) internal view returns (bool status){
        bool flag;
        accounts[user].bitmask & _bit == 0 ? flag = false : flag = true;
        return flag;
    }
    

    function ban_user(address user) public onlyAdmin returns(bool success){
        bitmask_add(user, 1024);
        return true;
    }
    function unban_user(address user) public onlyAdmin returns(bool success){
        bitmask_rm(user, 1024);
        return true;
    }
    function is_banned(address user) public view onlyAdmin returns (bool result){
        return bitmask_check(user, 1024);
    }
    



    
    function redenominate() public onlyAdmin returns(uint current_round){
        require(frozen == false); 
        require(round<9); 

        
        _totalSupply = _totalSupply.sub( team_fund%mul[round] ).sub( redenom_dao_fund%mul[round] ).sub( dec[8-round]*mul[round-1] );

        
        _totalSupply = ( _totalSupply / mul[round] ) * mul[round];
        team_fund = ( team_fund / mul[round] ) * mul[round]; 
        redenom_dao_fund = ( redenom_dao_fund / mul[round] ) * mul[round]; 

        if(round>1){
            
            uint superold = dec[(8-round)+1]; 

            
            epoch_fund = epoch_fund.add(superold * mul[round-2]);
            dec[(8-round)+1] = 0;
        }

        
        if(round<8){ 

            uint unclimed = dec[8-round]; 
            
            uint total_current = dec[8-1-round]; 
            

            
            if(total_current==0){
                current_toadd = [0,0,0,0,0,0,0,0,0]; 
                round++;
                return round;
            }

            
            uint[9] memory numbers  =[uint(1),2,3,4,5,6,7,8,9]; 
            uint[9] memory ke9  =[uint(0),0,0,0,0,0,0,0,0]; 
            uint[9] memory k2e9  =[uint(0),0,0,0,0,0,0,0,0]; 

            uint k05summ = 0;

                for (uint k = 0; k < ke9.length; k++) {
                     
                    ke9[k] = numbers[k]*1e9/total_current;
                    if(k<5) k05summ += ke9[k];
                }             
                for (uint k2 = 5; k2 < k2e9.length; k2++) {
                    k2e9[k2] = uint(ke9[k2])+uint(k05summ)*uint(weight[k2])/uint(100);
                }
                for (uint n = 5; n < current_toadd.length; n++) {
                    current_toadd[n] = k2e9[n]*unclimed/10/1e9;
                }
                
                
        }else{
            if(round==8){
                
                epoch_fund = epoch_fund.add(dec[0] * 10000000); 
                dec[0] = 0;
            }
            
        }

        round++;
        emit Redenomination(round);
        return round;
    }

   
    
    
    function updateAccount(address account) public returns(uint new_balance){
        require(frozen == false); 
        require(round<=9);
        require(bitmask_check(account, 1024) == false); 

        if(round > accounts[account].lastRound){

            if(round >1 && round <=8){


                
                uint tempDividedBalance = accounts[account].balance/current_mul();
                
                uint newFixedBalance = tempDividedBalance*current_mul();
                
                uint lastActiveDigit = tempDividedBalance%10;
                 
                uint diff = accounts[account].balance - newFixedBalance;
                

                if(diff > 0){
                    accounts[account].balance = newFixedBalance;
                    emit Transfer(account, address(0), diff);
                }

                uint toBalance = 0;
                if(lastActiveDigit>0 && current_toadd[lastActiveDigit-1]>0){
                    toBalance = current_toadd[lastActiveDigit-1] * current_mul();
                }


                if(toBalance > 0 && toBalance < dec[8-round+1]){ 

                    renewDec( accounts[account].balance, accounts[account].balance.add(toBalance) );
                    emit Transfer(address(0), account, toBalance);
                    
                    accounts[account].balance = accounts[account].balance.add(toBalance);
                    
                    dec[8-round+1] = dec[8-round+1].sub(toBalance);
                    
                    _totalSupply = _totalSupply.add(toBalance);
                    
                }

                accounts[account].lastRound = round;
                
                return accounts[account].balance;
                
            }else{
                if( round == 9){ 

                    uint newBalance = fix_amount(accounts[account].balance);
                    uint _diff = accounts[account].balance.sub(newBalance);

                    if(_diff > 0){
                        renewDec( accounts[account].balance, newBalance );
                        accounts[account].balance = newBalance;
                        emit Transfer(account, address(0), _diff);
                    }

                    accounts[account].lastRound = round;
                    
                    return accounts[account].balance;
                    
                }
            }
        }
    }

    
    
    function current_mul() internal view returns(uint _current_mul){
        return mul[round-1];
    }
    
    
    function fix_amount(uint amount) public view returns(uint fixed_amount){
        return ( amount / current_mul() ) * current_mul();
    }
    
    function get_rest(uint amount) internal view returns(uint fixed_amount){
        return amount % current_mul();
    }



    
    
    
    function totalSupply() public view returns (uint) {
        return _totalSupply;
    }
    
    
    
    function balanceOf(address tokenOwner) public constant returns (uint balance) {
        return accounts[tokenOwner].balance;
    }
    
    
    
    
    
    function allowance(address tokenOwner, address spender) public constant returns (uint remaining) {
        return allowed[tokenOwner][spender];
    }
    
    
    
    
    
    
    function transfer(address to, uint tokens) public returns (bool success) {
        require(frozen == false); 
        require(to != address(0));
        require(bitmask_check(to, 1024) == false); 

        
        tokens = fix_amount(tokens);
        
        require(tokens>0);

        
        updateAccount(to);
        updateAccount(msg.sender);

        uint fromOldBal = accounts[msg.sender].balance;
        uint toOldBal = accounts[to].balance;

        accounts[msg.sender].balance = accounts[msg.sender].balance.sub(tokens);
        accounts[to].balance = accounts[to].balance.add(tokens);

        require(renewDec(fromOldBal, accounts[msg.sender].balance));
        require(renewDec(toOldBal, accounts[to].balance));

        emit Transfer(msg.sender, to, tokens);
        return true;
    }


    
    
    
    
    
    
    
    
    function approve(address spender, uint tokens) public returns (bool success) {
        require(frozen == false); 
        require(bitmask_check(msg.sender, 1024) == false); 
        allowed[msg.sender][spender] = tokens;
        emit Approval(msg.sender, spender, tokens);
        return true;
    }
    
    
    
    
    
    
    
    
    
    function transferFrom(address from, address to, uint tokens) public returns (bool success) {
        require(frozen == false); 
        require(bitmask_check(to, 1024) == false); 
        updateAccount(from);
        updateAccount(to);

        uint fromOldBal = accounts[from].balance;
        uint toOldBal = accounts[to].balance;

        accounts[from].balance = accounts[from].balance.sub(tokens);
        allowed[from][msg.sender] = allowed[from][msg.sender].sub(tokens);
        accounts[to].balance = accounts[to].balance.add(tokens);

        require(renewDec(fromOldBal, accounts[from].balance));
        require(renewDec(toOldBal, accounts[to].balance));

        emit Transfer(from, to, tokens);
        return true; 
    }
    
    
    
    
    
    function approveAndCall(address spender, uint tokens, bytes data) public returns (bool success) {
        require(frozen == false); 
        require(bitmask_check(msg.sender, 1024) == false); 
        allowed[msg.sender][spender] = tokens;
        emit Approval(msg.sender, spender, tokens);
        ApproveAndCallFallBack(spender).receiveApproval(msg.sender, tokens, this, data);
        return true;
    }
    
    
    
    function () public payable {
        revert();
    } 

    
    
    
    function transferAnyERC20Token(address tokenAddress, uint tokens) public onlyOwner returns (bool success) {
        require(frozen == false); 
        return ERC20Interface(tokenAddress).transfer(owner, tokens);
    }




}