contract LexTokenFactory {
    // presented by OpenESQ || lexDAO LLC ~ Use at own risk!
    uint8 public version = 3;
    
    // factory settings
    string public stamp;
    uint256 public factoryFee;
    address public deployer;
    address payable public _lexDAO; 
    bool public _certified;
    bool public gated;
    
    LexToken private LT;
    address[] public tokens; 
    
    event CertificationUpdated(bool indexed updatedCertification);
    event FactoryFeeUpdated(uint256 indexed updatedFactoryFee);
    event LexDAOPaid(string indexed details, uint256 indexed payment);
    event LexDAOUpdated(address indexed updatedLexDAO);
    event LexTokenDeployed(address indexed LT, address indexed owner);
    
    constructor (
        string memory _stamp, 
        uint256 _factoryFee, 
        address _deployer, 
        address payable lexDAO,
        bool certified,
        bool _gated) public 
	{
        stamp = _stamp;
        factoryFee = _factoryFee;
        deployer = _deployer;
        _lexDAO = lexDAO;
        _certified = certified;
        gated = _gated;
	}
    
    function newLexToken( // public can issue stamped lex token for factory ether (Ξ) fee
        string memory name, 
		string memory symbol,
		string memory _stamp,
		uint8 decimals,
		uint256 cap,
		uint256 initialSupply,
		address owner) payable public {
		require(msg.value == factoryFee);
		require(_lexDAO != address(0));
		
		if (gated == true) {
            require(msg.sender == deployer); // function restricted to deployer if gated factory
        }
        
        LT = new LexToken(
            name, 
            symbol, 
            _stamp,
            decimals,
            cap,
            initialSupply,
            owner,
            _lexDAO,
            _certified);
        
        tokens.push(address(LT));
        address(_lexDAO).transfer(msg.value);
        emit LexTokenDeployed(address(LT), owner);
    }
    
    function getLexTokenCount() public view returns (uint256 LexTokenCount) {
        return tokens.length;
    }
    
    /***************
    LEXDAO FUNCTIONS
    ***************/
    function payLexDAO(string memory details) payable public { 
        _lexDAO.transfer(msg.value);
        emit LexDAOPaid(details, msg.value);
    }
    
    function updateCertification(bool updatedCertification) public {
        require(msg.sender == _lexDAO);
        _certified = updatedCertification;
        emit CertificationUpdated(updatedCertification);
    }
    
    function updateFactoryFee(uint256 updatedFactoryFee) public {
        require(msg.sender == _lexDAO);
        factoryFee = updatedFactoryFee;
        emit FactoryFeeUpdated(updatedFactoryFee);
    }
    
    function updateLexDAO(address payable updatedLexDAO) public {
        require(msg.sender == _lexDAO);
        _lexDAO = updatedLexDAO;
        emit LexDAOUpdated(updatedLexDAO);
    }
}
/**
 * @dev Factory pattern to clone new token contracts with lexDAO governance.
 */
function payLexDAO(string memory details) payable public { 
    _lexDAO.transfer(msg.value);
    emit LexDAOPaid(details, msg.value);
}

/***************
 LEXDAO FUNCTIONS
 ***************/