contract ShardRegistry is ERC20Detailed, ERC20Capped, ERC20Burnable, ERC20Pausable {

	IShardGovernor private _shardGovernor;
	enum ClaimWinner { None, Claimant, Counterclaimant }
	bool private _shotgunDisabled;

	constructor (
		uint256 cap,
		string memory name,
		string memory symbol,
		bool shotgunDisabled,
		address shardGovernorAddress
	) ERC20Detailed(name, symbol, 18) ERC20Capped(cap) public {
		_shardGovernor = IShardGovernor(shardGovernorAddress);
		_shotgunDisabled = shotgunDisabled;
	}

	/**
		* @notice Called to initiate Shotgun claim. Requires Ether.
		* @dev Transfers claimant's Shards into Governor contract's custody until
		claim is resolved.
		* @dev Forwards Ether to Shotgun contract through Governor contract.
		*/
	function lockShardsAndClaim() external payable {
		require(
				!_shotgunDisabled,
				"[lockShardsAndClaim] Shotgun disabled"
		);
		require(
			_shardGovernor.checkLock(),
			"[lockShardsAndClaim] NFT not locked, Shotgun cannot be triggered"
		);
		require(
			_shardGovernor.checkShotgunState(),
			"[lockShardsAndClaim] Shotgun already in progress"
		);
		require(
			msg.value > 0,
			"[lockShardsAndClaim] Transaction must send ether to activate Shotgun Clause"
		);
		uint initialClaimantBalance = balanceOf(msg.sender);
		require(
			initialClaimantBalance > 0,
			"[lockShardsAndClaim] Account does not own Shards"
		);
		require(
			initialClaimantBalance < cap(),
			"[lockShardsAndClaim] Account owns all Shards"
		);
		transfer(address(_shardGovernor), balanceOf(msg.sender));
		(bool success) = _shardGovernor.claimInitialShotgun.value(msg.value)(
			msg.sender, initialClaimantBalance
		);
		require(
			success,
			"[lockShards] Ether forwarding unsuccessful"
		);
	}

	/**
		* @notice Called to collect Ether from Shotgun proceeds. Burns Shard holdings.
		* @dev can be called in both Shotgun outcome scenarios by:
		- Initial claimant, if they lose the claim to counterclaimants and their
		Shards are bought out
		- Counterclaimants, bought out if initial claimant is successful.
		* @dev initial claimant does not own Shards at this point because they have
		been custodied in Governor contract at start of Shotgun.
		* @param shotgunClause address of the relevant Shotgun contract.
		*/
	function burnAndCollectEther(address shotgunClause) external {
		IShotgunClause _shotgunClause = IShotgunClause(shotgunClause);
		bool enacted = _shotgunClause.shotgunEnacted();
		if (!enacted) {
			_shotgunClause.enactShotgun();
		}
		require(
			enacted || _shotgunClause.shotgunEnacted(),
			"[burnAndCollectEther] Shotgun Clause not enacted"
		);
		uint balance = balanceOf(msg.sender);
		require(
			balance > 0 || msg.sender == _shotgunClause.initialClaimantAddress(),
			"[burnAndCollectEther] Account does not own Shards"
		);
		require(
			uint(_shotgunClause.claimWinner()) == uint(ClaimWinner.Claimant) &&
			msg.sender != _shotgunClause.initialClaimantAddress() ||
			uint(_shotgunClause.claimWinner()) == uint(ClaimWinner.Counterclaimant) &&
			msg.sender == _shotgunClause.initialClaimantAddress(),
			"[burnAndCollectEther] Account does not have right to collect ether"
		);
		burn(balance);
		_shotgunClause.collectEtherProceeds(balance, msg.sender);
	}

	function shotgunDisabled() external view returns (bool) {
		return _shotgunDisabled;
	}
}
/**
 	* @title ERC20 base for Shards with additional methods related to governance
 	* @author Joel Hubert (Metalith.io)
 	* @dev OpenZeppelin contracts are not ready for 0.6.0 yet, using 0.5.16.
 	*/
function lockShardsAndClaim() external payable {
	require(
			!_shotgunDisabled,
			"[lockShardsAndClaim] Shotgun disabled"
	);
	require(
		_shardGovernor.checkLock(),
		"[lockShardsAndClaim] NFT not locked, Shotgun cannot be triggered"
	);
	require(
		_shardGovernor.checkShotgunState(),
		"[lockShardsAndClaim] Shotgun already in progress"
	);
	require(
		msg.value > 0,
		"[lockShardsAndClaim] Transaction must send ether to activate Shotgun Clause"
	);
	uint initialClaimantBalance = balanceOf(msg.sender);
	require(
		initialClaimantBalance > 0,
		"[lockShardsAndClaim] Account does not own Shards"
	);
	require(
		initialClaimantBalance < cap(),
		"[lockShardsAndClaim] Account owns all Shards"
	);
	transfer(address(_shardGovernor), balanceOf(msg.sender));
	(bool success) = _shardGovernor.claimInitialShotgun.value(msg.value)(
		msg.sender, initialClaimantBalance
	);
	require(
		success,
		"[lockShards] Ether forwarding unsuccessful"
	);
}

/**
 		* @notice Called to initiate Shotgun claim. Requires Ether.
 		* @dev Transfers claimant's Shards into Governor contract's custody until
 		claim is resolved.
 		* @dev Forwards Ether to Shotgun contract through Governor contract.
 		*/