Skip to content

Instantly share code, notes, and snippets.

@rodrigosetti
Created December 29, 2018 18:44
Show Gist options
  • Save rodrigosetti/bf2a315795f25843445eecacfc4e6efb to your computer and use it in GitHub Desktop.
Save rodrigosetti/bf2a315795f25843445eecacfc4e6efb to your computer and use it in GitHub Desktop.
Created using remix-ide: Realtime Ethereum Contract Compiler and Runtime. Load this file by pasting this gists URL or ID at https://remix.ethereum.org/#version=soljson-v0.5.2+commit.1df8f40c.js&optimize=true&gist=
pragma solidity >=0.4.22 <0.6.0;
contract BettingPool {
// constructor
uint public betDeadline;
uint public secretDeadline;
// phase 1 (bets)
mapping (address => uint256) bets;
mapping (address => bytes32) secretHashes;
// phase 2 (secrets)
// accumulated bets so far before the sender
mapping (address => uint256) accumulatedBets;
uint256 confirmedValue;
uint256 random;
constructor(uint betDuration, uint secretDuration) public {
betDeadline = now + betDuration;
secretDeadline = betDeadline + secretDuration;
confirmedValue = 0;
random = uint256(blockhash(block.number));
}
function placeBet(uint256 secretHash) external payable {
require(msg.value > 0, "bet must be more than zero");
require(now <= betDeadline, "betting is closed for this pool");
require(bets[msg.sender] == 0, "sender has already placed a bet");
// add participant to bet pool (address, bet, secret hash)
secretHashes[msg.sender] = bytes32(secretHash);
bets[msg.sender] = msg.value;
}
function computeSecretHash(uint256 secret) public pure returns (bytes32) {
return sha256(abi.encode(secret));
}
function sendSecret(uint256 secret) external {
require(now > betDeadline, "betting is still open for this pool");
require(now <= secretDeadline, "secret is closed for this pool");
uint256 bet = bets[msg.sender];
require(bet > 0, "sender hasn't placed any bets");
require(computeSecretHash(secret) == secretHashes[msg.sender],
"secret doesn't match");
require(accumulatedBets[msg.sender] == 0, "secret already sent");
random ^= secret;
accumulatedBets[msg.sender] = confirmedValue;
confirmedValue += bet;
}
function collectReward() external returns (bool hasWon) {
require(secretDeadline < now,
"bet pool is not ready to collecting rewards yet.");
require(bets[msg.sender] > 0, "sender hasn't placed any bets");
require(address(this).balance > 0, "reward already collected");
hasWon = didIWin();
if (hasWon) {
// if sender is winner: transfer this contract's balance
msg.sender.transfer(address(this).balance);
}
}
function didIWin() view public returns (bool) {
require(bets[msg.sender] > 0, "sender hasn't placed any bets");
uint256 betRange = random % confirmedValue;
return accumulatedBets[msg.sender] <= betRange &&
betRange < accumulatedBets[msg.sender] + bets[msg.sender];
}
}
pragma solidity >=0.4.0 <0.6.0;
import "remix_tests.sol"; // this import is automatically injected by Remix.
// file name has to end with '_test.sol'
contract test_1 {
function beforeAll() public {
// here should instantiate tested contract
Assert.equal(uint(4), uint(3), "error in before all function");
}
function check1() public {
// use 'Assert' to test the contract
Assert.equal(uint(2), uint(1), "error message");
Assert.equal(uint(2), uint(2), "error message");
}
function check2() public view returns (bool) {
// use the return value (true or false) to test the contract
return true;
}
}
contract test_2 {
function beforeAll() public {
// here should instantiate tested contract
Assert.equal(uint(4), uint(3), "error in before all function");
}
function check1() public {
// use 'Assert' to test the contract
Assert.equal(uint(2), uint(1), "error message");
Assert.equal(uint(2), uint(2), "error message");
}
function check2() public view returns (bool) {
// use the return value (true or false) to test the contract
return true;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment