contract InflationaryToken is ERC20, ERC20Permit {
    /// @dev Defines the cowDao address that is allowed to mint new tokens
    address public immutable cowDao;
    /// @dev Defines how frequently inflation can be triggered: Once a year
    uint256 public constant TIME_BETWEEN_MINTINGS = 365 days;
    /// @dev Defines the maximal inflation per year
    uint256 public constant MAX_YEARLY_INFLATION = 3;
    /// @dev Stores the timestamp of the last inflation event
    uint256 public timestampLastMinting = 0;

    /// @dev Error caused by an attempt to mint too many tokens.
    error ExceedingMintCap();
    /// @dev Error caused by calling the mint function more than once within one year.
    error AlreadyInflated();
    /// @dev Error caused by calling the mint function from a non-cowDao account.
    error OnlyCowDao();

    modifier onlyCowDao() {
        if (msg.sender != cowDao) {
            revert OnlyCowDao();
        }
        _;
    }

    constructor(
        address initialTokenHolder,
        address _cowDao,
        uint256 totalSupply,
        string memory erc20Name,
        string memory erc20Symbol
    ) ERC20(erc20Name, erc20Symbol) ERC20Permit(erc20Name) {
        _mint(initialTokenHolder, totalSupply);
        cowDao = _cowDao;
        // solhint-disable-next-line not-rely-on-time
        timestampLastMinting = block.timestamp;
    }

    /// @dev This function allows to mint new tokens
    /// @param target The address that should receive the new tokens
    /// @param amount The amount of tokens to be minted.
    function mint(address target, uint256 amount) external onlyCowDao {
        if (amount > (totalSupply() * MAX_YEARLY_INFLATION) / 100) {
            revert ExceedingMintCap();
        }
        // solhint-disable-next-line not-rely-on-time
        if (timestampLastMinting + TIME_BETWEEN_MINTINGS > block.timestamp) {
            revert AlreadyInflated();
        }
        timestampLastMinting = block.timestamp; // solhint-disable-line not-rely-on-time
        _mint(target, amount);
    }
}
/// @dev Contract contains the logic for minting new tokens
/// @title Mintable Token
/// @author CoW Protocol Developers
function mint(address target, uint256 amount) external onlyCowDao {
    if (amount > (totalSupply() * MAX_YEARLY_INFLATION) / 100) {
        revert ExceedingMintCap();
    }
    // solhint-disable-next-line not-rely-on-time
    if (timestampLastMinting + TIME_BETWEEN_MINTINGS > block.timestamp) {
        revert AlreadyInflated();
    }
    timestampLastMinting = block.timestamp; // solhint-disable-line not-rely-on-time
    _mint(target, amount);
}

/// @dev This function allows to mint new tokens
/// @param target The address that should receive the new tokens
/// @param amount The amount of tokens to be minted.