contract LCPSignaling is LORTokenWrapper, ReentrancyGuard, Pausable, Ownable {
	address public lotAddress;

	mapping(uint256 => bool) private _generated;

	event Deposited(address indexed user, uint256 id, uint256 amount);
	event Withdrawn(address indexed user, uint256 id, uint256 amount);
	event Claimed(address indexed user, uint256 id, uint256 amount);
	event Generated(address indexed user, uint256 id);

	constructor(address _lotAddress, address _lorAddress) public {
		lotAddress = _lotAddress;
		lorToken = IERC20(_lorAddress);

		lorToken.safeApprove(_lotAddress, (2**256 - 1));
	}

	modifier onlyLOT() {
		require(msg.sender == lotAddress, "only LOT allowed");
		_;
	}

	function deposit(uint256 id, uint256 amount) public nonReentrant whenNotPaused() {
		require(amount % 1 ether == 0, "Deposit only increments of 1");
		require(!_generated[id], "LOT generated; no new deposits");
		super.deposit(id, amount);
		emit Deposited(msg.sender, id, amount);
	}

	function withdraw(uint256 id, uint256 amount) public nonReentrant {
		require(amount > 0, "Cannot withdraw 0");
		require(!_generated[id], "LOT generated; did you intend to claim?");
		require(amount % 1 ether == 0, "Withdraw only increments of 1");

		super.withdraw(id, amount);
		emit Withdrawn(msg.sender, id, amount);
	}

	function claim(uint256 id) public nonReentrant {
		require(_generated[id], "LOT not generated; did you intend to withdraw?");
		require(super.balanceOf(msg.sender, id) > 0, "Nothing to claim");

		uint256 amount = super.balanceOf(msg.sender, id);
		super.claim(id, msg.sender);
		IERC1155(lotAddress).lcpMint(id, msg.sender, _toEther(amount), "");
		emit Claimed(msg.sender, id, _toEther(amount));
	}

	function claimable(address account, uint256 id) public view returns (uint256) {
		if (!_generated[id]) {
			return 0;
		}
		return _toEther(super.balanceOf(account, id));
	}

	function generate(uint256 id) public onlyLOT returns (uint256) {
		_generated[id] = true;
		emit Generated(msg.sender, id);
		return totalDeposits(id);
	}

	// Internal functions
	function _toEther(uint256 _amount) internal pure returns (uint256) {
		return _amount / (1 ether);
	}
}
function _toEther(uint256 _amount) internal pure returns (uint256) {
	return _amount / (1 ether);
}

// Internal functions