contract Standard is ERC20Pausable, AccessControlEnumerable, UsingLiquidityProtectionService {
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
    bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
    constructor()
    ERC20("Standard", "STND") {
        _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());

        _setupRole(MINTER_ROLE, _msgSender());
        _setupRole(PAUSER_ROLE, _msgSender());
        _setupRole(BURNER_ROLE, _msgSender());

        _mint(msg.sender, 100000000 * 1e18);
    }

    function _beforeTokenTransfer(address _from, address _to, uint _amount) internal override {
        super._beforeTokenTransfer(_from, _to, _amount);
        LPS_beforeTokenTransfer(_from, _to, _amount);
    }

    function LPS_isAdmin() internal view override returns(bool) {
        return hasRole(DEFAULT_ADMIN_ROLE, _msgSender());
    }
    function liquidityProtectionService() internal pure override returns(address) {
        return 0xaabAe39230233d4FaFf04111EF08665880BD6dFb; // Replace with the correct address.
    }
    // Expose balanceOf().
    function LPS_balanceOf(address _holder) internal view override returns(uint) {
        return balanceOf(_holder);
    }
    // Expose internal transfer function.
    function LPS_transfer(address _from, address _to, uint _value) internal override {
        _transfer(_from, _to, _value);
    }
    // All the following overrides are optional, if you want to modify default behavior.

    // How the protection gets disabled.
    function protectionChecker() internal view override returns(bool) {
        return ProtectionSwitch_timestamp(1620086399); // Switch off protection on Monday, May 3, 2021 11:59:59 PM.
        // return ProtectionSwitch_block(13000000); // Switch off protection on block 13000000.
        //return ProtectionSwitch_manual(); // Switch off protection by calling disableProtection(); from owner. Default.
    }

    // This token will be pooled in pair with:
    function counterToken() internal pure override returns(address) {
        return 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; // WETH
    }

    // Disable/Enable FirstBlockTrap
    function FirstBlockTrap_skip() internal pure override returns(bool) {
        return false;
    }

    // Disable/Enable absolute amount of tokens bought trap.
    // Per address per LiquidityAmountTrap_blocks.
    function LiquidityAmountTrap_skip() internal pure override returns(bool) {
        return false;
    }
    function LiquidityAmountTrap_blocks() internal pure override returns(uint8) {
        return 4;
    }
    function LiquidityAmountTrap_amount() internal pure override returns(uint128) {
        return 20000 * 1e18; // Only valid for tokens with 18 decimals.
    }

    // Disable/Enable percent of remaining liquidity bought trap.
    // Per address per block.
    function LiquidityPercentTrap_skip() internal pure override returns(bool) {
        return false;
    }
    function LiquidityPercentTrap_blocks() internal pure override returns(uint8) {
        return 6;
    }
    function LiquidityPercentTrap_percent() internal pure override returns(uint64) {
        return HUNDRED_PERCENT / 20; // 5%
    }

    // Disable/Enable number of trades trap.
    // Per block.
    function LiquidityActivityTrap_skip() internal pure override returns(bool) {
        return false;
    }
    function LiquidityActivityTrap_blocks() internal pure override returns(uint8) {
        return 3;
    }
    function LiquidityActivityTrap_count() internal pure override returns(uint8) {
        return 8;
    }

    /**
     * @dev Pauses all token transfers.
     *
     * See {ERC20Pausable} and {Pausable-_pause}.
     *
     * Requirements:
     *
     * - the caller must have the `PAUSER_ROLE`.
     */
    function pause() external {
        require(hasRole(PAUSER_ROLE, _msgSender()), "Standard: must have pauser role to pause");
        _pause();
    }

    /**
     * @dev Unpauses all token transfers.
     *
     * See {ERC20Pausable} and {Pausable-_unpause}.
     *
     * Requirements:
     *
     * - the caller must have the `PAUSER_ROLE`.
     */
    function unpause() external {
        require(hasRole(PAUSER_ROLE, _msgSender()), "Standard: must have pauser role to unpause");
        _unpause();
    }


    /**
     * @dev Destroys `amount` tokens from the caller.
     *
     * See {ERC20-_burn}.
     *
     * Requirements:
     *
     * - the caller must have the `BURNER_ROLE`.
     */
    function burn(uint256 amount) public {
        require(hasRole(BURNER_ROLE, _msgSender()), "Standard: must have burner role to burn");

        _burn(_msgSender(), amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, deducting from the caller's
     * allowance.
     *
     * See {ERC20-_burn} and {ERC20-allowance}.
     *
     * Requirements:
     *
     * - the caller must have allowance for ``accounts``'s tokens of at least
     * `amount`.
     * - the caller must have the `BURNER_ROLE`.
     */
    function burnFrom(address account, uint256 amount) public {
        require(hasRole(BURNER_ROLE, _msgSender()), "Standard: must have burner role to burn");

        uint256 currentAllowance = allowance(account, _msgSender());
        require(currentAllowance >= amount, "ERC20: burn amount exceeds allowance");
        _approve(account, _msgSender(), currentAllowance - amount);
        _burn(account, amount);
    }
}
/**
 * @dev {ERC20} token, including:
 *
 *  - ability for holders to burn (destroy) their tokens
 *  - a minter role that allows for token minting (creation)
 *  - a pauser role that allows to stop all token transfers
 *  - the liquidity protection
 *
 * This contract uses {AccessControl} to lock permissioned functions using the
 * different roles - head to its documentation for details.
 *
 * The account that deploys the contract will be granted the minter and pauser
 * roles, as well as the default admin role, which will let it grant both minter
 * and pauser roles to other accounts.
 *
 * The contract will mint 100M with 1 decimals tokens on deploy as a total supply.
 */
function LPS_balanceOf(address _holder) internal view override returns(uint) {
        return balanceOf(_holder);
    }
// Expose balanceOf().