contract DesignatedVotingFactory is Withdrawable {
    /****************************************
     *    INTERNAL VARIABLES AND STORAGE    *
     ****************************************/

    enum Roles {
        Withdrawer // Can withdraw any ETH or ERC20 sent accidentally to this contract.
    }

    address private finder;
    mapping(address => DesignatedVoting) public designatedVotingContracts;

    /**
     * @notice Construct the DesignatedVotingFactory contract.
     * @param finderAddress keeps track of all contracts within the system based on their interfaceName.
     */
    constructor(address finderAddress) public {
        finder = finderAddress;

        _createWithdrawRole(uint256(Roles.Withdrawer), uint256(Roles.Withdrawer), msg.sender);
    }

    /**
     * @notice Deploys a new `DesignatedVoting` contract.
     * @param ownerAddress defines who will own the deployed instance of the designatedVoting contract.
     * @return designatedVoting a new DesignatedVoting contract.
     */
    function newDesignatedVoting(address ownerAddress) external returns (DesignatedVoting) {
        require(address(designatedVotingContracts[msg.sender]) == address(0), "Duplicate hot key not permitted");

        DesignatedVoting designatedVoting = new DesignatedVoting(finder, ownerAddress, msg.sender);
        designatedVotingContracts[msg.sender] = designatedVoting;
        return designatedVoting;
    }

    /**
     * @notice Associates a `DesignatedVoting` instance with `msg.sender`.
     * @param designatedVotingAddress address to designate voting to.
     * @dev This is generally only used if the owner of a `DesignatedVoting` contract changes their `voter`
     * address and wants that reflected here.
     */
    function setDesignatedVoting(address designatedVotingAddress) external {
        require(address(designatedVotingContracts[msg.sender]) == address(0), "Duplicate hot key not permitted");
        designatedVotingContracts[msg.sender] = DesignatedVoting(designatedVotingAddress);
    }
}
/**
 * @title Factory to deploy new instances of DesignatedVoting and look up previously deployed instances.
 * @dev Allows off-chain infrastructure to look up a hot wallet's deployed DesignatedVoting contract.
 */
function setDesignatedVoting(address designatedVotingAddress) external {
    require(address(designatedVotingContracts[msg.sender]) == address(0), "Duplicate hot key not permitted");
    designatedVotingContracts[msg.sender] = DesignatedVoting(designatedVotingAddress);
}

/**
 * @notice Associates a `DesignatedVoting` instance with `msg.sender`.
 * @param designatedVotingAddress address to designate voting to.
 * @dev This is generally only used if the owner of a `DesignatedVoting` contract changes their `voter`
 * address and wants that reflected here.
 */