abstract contract MaxBuyDynamic is ERC20 {
    uint256 public maxBuy;
    uint256 constant maxBuyIncrementMinutesTimer = 2; // increment maxbuy minutes
    uint256 constant maxBuyIncrementPercentil = 1; // increment maxbyu percentil 1000=100%
    uint256 public maxBuyIncrementValue; // value for increment maxBuy
    uint256 public incrementTime; // last increment time

    function startMaxBuyDynamic() internal {
        incrementTime = block.timestamp;
        maxBuyIncrementValue = (_totalSupply * maxBuyIncrementPercentil) / 1000;
    }

    function checkAndIncrementMaxBuyLimit(uint256 amount) internal {
        // increment maxBuy
        uint256 incrementCount = (block.timestamp - incrementTime) /
            (maxBuyIncrementMinutesTimer * 1 minutes);
        if (incrementCount > 0) {
            if (maxBuy < _totalSupply) {
                unchecked {
                    maxBuy += maxBuyIncrementValue * incrementCount;
                }
            }
            incrementTime = block.timestamp;
        }
        // maxBuy limitation
        require(amount <= maxBuy);
    }

    function getMaxBuy() external view returns (uint256) {
        uint256 incrementCount = (block.timestamp - incrementTime) /
            (maxBuyIncrementMinutesTimer * 1 minutes);
        if (incrementCount == 0) return maxBuy;

        return maxBuy + maxBuyIncrementValue * incrementCount;
    }

    function setMaxBuyPercentil(uint256 percentil) internal {
        maxBuy = (_totalSupply * percentil) / 1000;
    }
}
function startMaxBuyDynamic() internal {
    incrementTime = block.timestamp;
    maxBuyIncrementValue = (_totalSupply * maxBuyIncrementPercentil) / 1000;
}

// last increment time