tbtc - Funder loses payment to keep if signing group is not established in time  Pending
To create a new deposit, the funder has to pay for the creation of a keep. If establishing the keep does not succeed in time, fails or the signing group decides not to return a public key when `retrieveSignerPubkey` is called to transition from `awaiting_signer_setup` to `awaiting_btc_funding_proof` the signer setup fails. After a timeout of 3 hrs, anyone can force the deposit to transition from `awaiting_signer_setup` to `failed_setup` by calling `notifySignerSetupFailure`.\\nThe funder had to provide payment for the keep but the signing group failed to establish. Payment for the keep is not returned even though one could assume that the signing group tried to play unfairly. The signing group might intentionally try to cause this scenario to interfere with the system.\\n`retrieveSignerPubkey` fails if keep provided pubkey is empty or of an unexpected length\\n```\\n/// @notice we poll the Keep contract to retrieve our pubkey\\n/// @dev We store the pubkey as 2 bytestrings, X and Y.\\n/// @param \\_d deposit storage pointer\\n/// @return True if successful, otherwise revert\\nfunction retrieveSignerPubkey(DepositUtils.Deposit storage \\_d) public {\\n    require(\\_d.inAwaitingSignerSetup(), "Not currently awaiting signer setup");\\n\\n    bytes memory \\_publicKey = IBondedECDSAKeep(\\_d.keepAddress).getPublicKey();\\n    require(\\_publicKey.length == 64, "public key not set or not 64-bytes long");\\n\\n    \\_d.signingGroupPubkeyX = \\_publicKey.slice(0, 32).toBytes32();\\n    \\_d.signingGroupPubkeyY = \\_publicKey.slice(32, 32).toBytes32();\\n    require(\\_d.signingGroupPubkeyY != bytes32(0) && \\_d.signingGroupPubkeyX != bytes32(0), "Keep returned bad pubkey");\\n    \\_d.fundingProofTimerStart = block.timestamp;\\n\\n    \\_d.setAwaitingBTCFundingProof();\\n    \\_d.logRegisteredPubkey(\\n        \\_d.signingGroupPubkeyX,\\n        \\_d.signingGroupPubkeyY);\\n}\\n```\\n\\n`notifySignerSetupFailure` can be called by anyone after a timeout of 3hrs\\n```\\n/// @notice Anyone may notify the contract that signing group setup has timed out\\n/// @dev We rely on the keep system punishes the signers in this case\\n/// @param \\_d deposit storage pointer\\nfunction notifySignerSetupFailure(DepositUtils.Deposit storage \\_d) public {\\n    require(\\_d.inAwaitingSignerSetup(), "Not awaiting setup");\\n    require(\\n        block.timestamp > \\_d.signingGroupRequestedAt + TBTCConstants.getSigningGroupFormationTimeout(),\\n        "Signing group formation timeout not yet elapsed"\\n    );\\n    \\_d.setFailedSetup();\\n    \\_d.logSetupFailed();\\n\\n    fundingTeardown(\\_d);\\n}\\n```\\n
It should be ensured that a keep group always establishes or otherwise the funder is refunded the fee for the keep.
```\\n/// @notice we poll the Keep contract to retrieve our pubkey\\n/// @dev We store the pubkey as 2 bytestrings, X and Y.\\n/// @param \\_d deposit storage pointer\\n/// @return True if successful, otherwise revert\\nfunction retrieveSignerPubkey(DepositUtils.Deposit storage \\_d) public {\\n    require(\\_d.inAwaitingSignerSetup(), "Not currently awaiting signer setup");\\n\\n    bytes memory \\_publicKey = IBondedECDSAKeep(\\_d.keepAddress).getPublicKey();\\n    require(\\_publicKey.length == 64, "public key not set or not 64-bytes long");\\n\\n    \\_d.signingGroupPubkeyX = \\_publicKey.slice(0, 32).toBytes32();\\n    \\_d.signingGroupPubkeyY = \\_publicKey.slice(32, 32).toBytes32();\\n    require(\\_d.signingGroupPubkeyY != bytes32(0) && \\_d.signingGroupPubkeyX != bytes32(0), "Keep returned bad pubkey");\\n    \\_d.fundingProofTimerStart = block.timestamp;\\n\\n    \\_d.setAwaitingBTCFundingProof();\\n    \\_d.logRegisteredPubkey(\\n        \\_d.signingGroupPubkeyX,\\n        \\_d.signingGroupPubkeyY);\\n}\\n```\\n