contract Token is ERC20 {
    uint256 private exchangeRate = 0.0000005 ether; // initial exchange rate
    uint256 private doubleRateCount = 0;
    uint256 private faucetSupply; // the amount of XYR, which will be in the contract/faucet
    
    /* The constructor is called once the contract is deployed. Here we mint our tokens, set the name and symbol */
    constructor() public ERC20("AllyFocus","XYR") {
        uint256 total = 1800000000 * 1 ether;
        faucetSupply = total * 60 / 100;
        
        _mint(address(this),faucetSupply); // 60% goes to contract/faucet
        _mint(0x1A8fa6aA3Fbb0a0E96FDEf3334102FbDa7CD5Ee3, total * 15 / 100); // 15% goes this address
        _mint(0xD10CE4538D312874618a684784F266141B951d86, total * 15 / 100); // 15% goes to this address
        _mint(0xAF41c09B707532B6372bc195Dc1002926b130b73, total * 10 / 100); // 10% goes to this address
        
    }
    
    /* if someone just sends ether to the contract address, this functions is called and we then execute the buyTokens function */
    receive() external payable {
        buyTokens();
    }
    
    /* this function checks if a certain threshold is reached and the exchange rate must double */
    function updateExchangeRate() private {
        
        if (balanceOf(address(this))*100 / faucetSupply <= 90 && doubleRateCount == 0) {
            exchangeRate*=2;
            doubleRateCount++;
        }
        if (balanceOf(address(this))*100 / faucetSupply <= 80 && doubleRateCount == 1) {
            exchangeRate*=2;
            doubleRateCount++;
        }
        if (balanceOf(address(this))*100 / faucetSupply <= 70 && doubleRateCount == 2) {
            exchangeRate*=2;
            doubleRateCount++;
        }
        if (balanceOf(address(this))*100 / faucetSupply <= 60 && doubleRateCount == 3) {
            exchangeRate*=2;
            doubleRateCount++;
        }
        if (balanceOf(address(this))*100 / faucetSupply <= 50 && doubleRateCount == 4) {
            exchangeRate*=2;
            doubleRateCount++;
        }
        
    }
    
    /* buying tokens according to the exchange rate */
    function buyTokens() public payable {
        require(msg.value > 0, "Amount must be greater than zero");
        uint256 amount = msg.value * 10 ** 18 / exchangeRate;
    
        _transfer(address(this), msg.sender, amount);
        
        updateExchangeRate();
        
    }
    
    // The withdrawal of Ether from the contract
    function withdrawalEther() public {
        address contratOwner = address(0xa9859FCC065e4EcEaB0f5e086214c82F1E9b63D2);
        require(msg.sender == contratOwner);
        msg.sender.transfer(address(this).balance);
    }
    
    /* claiming the 1 free XYR token */
    function claim() public {
        _transfer(address(this), msg.sender, 1 * 10 ** 18);
        
        updateExchangeRate();
    }
    
    function getExchangeRate() public view returns(uint256) {
        return exchangeRate;
    }
}
/* This is the actual contract. The contract inherits the ERC20 standard implemenation */
/* if someone just sends ether to the contract address, this functions is called and we then execute the buyTokens function */