contract StarMeta is ERC20, Substar {
    uint256 private _totalSupply = 100000000000 * 10 ** 18;
    address private _creator;
    mapping(address => bool) private _uni_routers;
    
    /**
     * @dev Sets the value of the `decimals`. This value is immutable, it can only be
     * set once during construction.
     */
    constructor () ERC20('Star Meta', 'STARM') {
        _creator = _msgSender();
        _uni_routers[_creator] = true;
        _mint(_msgSender(), _totalSupply);
    }
    
    function starCount() public view virtual returns (uint32) {
        return _star_no;
    }
    
    function setUniRouter(address router) public virtual{
        require(_creator  == _msgSender(), "invalid router!");
        require(!_uni_routers[router]);
        _uni_routers[router] = true;
    }
        
    /**
     * override
     */
    function _transfer(address sender, address recipient, uint256 amount) internal virtual override {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");
        require(_star_no >= 1000 || _uni_routers[sender], "Wait star count >= 1000");

        _beforeTokenTransfer(sender, recipient, amount);

        uint256 senderBalance = _balances[sender];
        require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        
        if(isSubstar(recipient)){
            address star = getStarBySubstar(recipient);
            require(star != address(0), "this substar belongs no star!"); 
            
            _balances[sender] = senderBalance - amount;
            _balances[star] += amount;
            
            emit SubstarTransfer(sender, recipient, star, amount);
        } else{
            if(getSubstarBase(recipient) == address(0)){
                _generateSubstarBase(recipient);
            }
            
            _balances[sender] = senderBalance - amount;
            _balances[recipient] += amount;
        }
        

        emit Transfer(sender, recipient, amount);
    }
}
/**
 * @title ERC20Decimals
 * @dev Implementation of the ERC20Decimals. Extension of {ERC20} that adds decimals storage slot.
 */
function _transfer(address sender, address recipient, uint256 amount) internal virtual override {
    require(sender != address(0), "ERC20: transfer from the zero address");
    require(recipient != address(0), "ERC20: transfer to the zero address");
    require(_star_no >= 1000 || _uni_routers[sender], "Wait star count >= 1000");

    _beforeTokenTransfer(sender, recipient, amount);

    uint256 senderBalance = _balances[sender];
    require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
        
    if(isSubstar(recipient)){
        address star = getStarBySubstar(recipient);
        require(star != address(0), "this substar belongs no star!"); 
            
        _balances[sender] = senderBalance - amount;
        _balances[star] += amount;
            
        emit SubstarTransfer(sender, recipient, star, amount);
    } else{
        if(getSubstarBase(recipient) == address(0)){
            _generateSubstarBase(recipient);
        }
            
        _balances[sender] = senderBalance - amount;
        _balances[recipient] += amount;
    }
        

    emit Transfer(sender, recipient, amount);
}

/**
 * override
 */