Skip to content

Instantly share code, notes, and snippets.

@e00dan
Last active April 14, 2021 16:21
Show Gist options
  • Save e00dan/19e84c22dca7cf97ff8c124770fccb24 to your computer and use it in GitHub Desktop.
Save e00dan/19e84c22dca7cf97ff8c124770fccb24 to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import '@openzeppelin/contracts/utils/cryptography/ECDSA.sol';
contract HeadTail {
address payable public userOneAddress;
bytes public userOneSignedChoiceHash;
address payable public userTwoAddress;
bool public userTwoChoice;
uint256 public userTwoChoiceSubmittedTime;
uint256 public stake;
// constructor(bytes memory _signedChoiceHash, uint128 _stake) payable {
// require(msg.value == _stake, "user has to pass asset value equal to second parameter of the constructor (stake)");
// stake = _stake;
// userOneAddress = payable(msg.sender);
// userOneSignedChoiceHash = _signedChoiceHash;
// }
function depositUserOne() public payable {
// require(msg.value == _stake, "user has to pass asset value equal to second parameter of the constructor (stake)");
require(userOneAddress == address(0), "userOneAddress can't be already set");
stake = msg.value;
userOneAddress = payable(msg.sender);
}
function depositUserTwo(bool choice) public payable {
require(
msg.value == stake,
'user has to pass asset value equal to second parameter of the constructor (stake)'
);
require(userTwoAddress == address(0), "userTwoAddress can't be already set");
require(userOneAddress != msg.sender, 'userTwoAddress has to differ from userOneAddress');
userTwoAddress = payable(msg.sender);
userTwoChoice = choice;
userTwoChoiceSubmittedTime = block.timestamp;
}
function revealUserOneChoice(bool choice, string memory secret) public returns (bool) {
require(
userTwoAddress != address(0),
'user two address has to be set before distributing prize'
);
// require(verify(createChoiceHash(choice, secret), userOneSignedChoiceHash) == userOneAddress, "choice signature has to be correct");
require(address(this).balance == 2 * stake, 'prize has to be not been distributed yet');
distributePrize(choice);
return true;
}
function timeout() public returns (bool) {
require(
userTwoAddress != address(0),
'user two address has to be set before distributing prize'
);
require(address(this).balance == 2 * stake, 'prize has to be not been distributed yet');
require(
block.timestamp >= userTwoChoiceSubmittedTime + 24 hours,
'24 hours need to pass before ability to call timeout'
);
userTwoAddress.transfer(2 * stake);
return true;
}
function verify(bytes32 hash, bytes memory signature) public pure returns (address) {
return ECDSA.recover(ECDSA.toEthSignedMessageHash(hash), signature);
}
function createChoiceHash(bool choice, string memory secret) public pure returns (bytes32) {
return keccak256(abi.encodePacked(choice, secret));
}
function distributePrize(bool userOneChoice) private returns (bool) {
if (userTwoChoice == userOneChoice) {
userTwoAddress.transfer(2 * stake);
} else {
userOneAddress.transfer(2 * stake);
}
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment